Maison  >  Article  >  développement back-end  >  Exemple d'analyse du verrouillage de fichier PHP et du verrouillage de processus

Exemple d'analyse du verrouillage de fichier PHP et du verrouillage de processus

小云云
小云云original
2018-01-30 10:41:281646parcourir

Compte tenu de l'introduction de swoole auparavant, utilisons le mécanisme serveur/client et multi-processus de swoole pour expliquer le verrouillage. Cet article présente principalement les exemples d'utilisation du verrouillage de fichier PHP et du verrouillage de processus. Ici, nous expliquons uniquement le mécanisme de verrouillage. de PHP. Étant donné que les verrous SQL sont différents dans leur mode d'action et leurs scénarios d'application, et seront expliqués séparément, j'espère que cela pourra aider tout le monde.

1. Verrouillage des fichiers

  • flock()

  • fclose()

  • swoole_lock()

Les scénarios d'application possibles du verrouillage de fichiers sont :

1. Limiter plusieurs processus simultanés ou plusieurs serveurs qui doivent accéder et modifier le même fichier ;

2. Mettre en file d'attente et bloquer artificiellement les processus participant aux E/S de fichiers ;

3. Garder le contenu des fichiers dans la logique métier ;

Ce qui suit est l'utilisation du mécanisme de communication C/S de verrouillage de fichier, le processus de communication spécifique a été omis

Serveur (le processus de communication du serveur a été omis) :

//监听数据发送事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
  $serv->send($fd, "ServerEnd");

  $p_file = "locktest.txt";
  var_dump(file_get_contents($p_file));
});

Client1 (Serveur processus de communication omis) :

$s_recv = "ww";

$p_file = "locktest.txt";

$o_file = fopen($p_file,'w+');
// flock()加锁方式:
flock($o_file,LOCK_EX);

// // swoole加锁方式:
// $lock = new swoole_lock(SWOOLE_FILELOCK, $p_file);
// $lock->lock();

fwrite($o_file, 'ss' . $s_recv);

sleep(30);
// 两种解锁方式
// flock($o_file, LOCK_UN);
// $lock->unlock();

Client2 (Processus de communication du serveur omis) :

$s_recv = "xx";

$p_file = "locktest.txt";

$o_file = fopen($p_file,'w+');
// flock()加锁方式:
flock($o_file,LOCK_EX);

// // swoole加锁方式:
// $lock = new swoole_lock(SWOOLE_FILELOCK, $p_file);
// $lock->lock();


fwrite($o_file, 'ss' . $s_recv);

// 两种解锁方式
// flock($o_file, LOCK_UN);
// $lock->unlock();

Résultat :

Client2 est bloqué 30s, le fichier est pas écrit une seule fois avant la fin de l'exécution de Client1 ;

[l0.16@4 m29.5% c30s04] $ php swoole_client2.php

Il convient de noter que :

1 Qu'il s'agisse de flock() ou de swoole_lock() fourni par swoole, il y a un. mécanisme pour se déverrouiller automatiquement à la fin du processus, afin qu'il puisse s'exécuter normalement même sans déverrouillage manuel dans la démo. Par conséquent, la fonction de pause sleep() est exécutée dans le premier client pour observer l'effet du verrouillage du fichier

2. La méthode de publication standard de flock() est flock($file,LOCK_UN);, mais personnellement, j'aime fclose() pour éviter de futurs problèmes ;


2. 🎜>

À la différence des verrous de fichiers, les verrous de processus ne sont pas utilisés pour empêcher les E/S sur les fichiers, mais sont utilisés pour éviter les conséquences inattendues causées par la concurrence multi-processus. Par conséquent, ils doivent être utilisés lorsque plusieurs processus sont simultanés. Mettre en file d'attente signifie bloquer l'exécution logique d'autres processus simultanés avant la fin de l'exécution logique clé d'un processus.

Il existe plusieurs idées d'implémentation :

1. Utilisez le verrouillage de fichier flock() pour créer un fichier temporaire. verrouillez le fichier, utilisez LOCK_NB pour simuler un flux bloquant ou non bloquant, puis utilisez des conditions de jugement pour contrôler l'exécution de la logique à l'intérieur du processus

Démo du modèle non bloquant :

2. Utilisez swoole pour fournir une mémoire partagée, une méthode de mise en cache ou une méthode de communication pour transférer une variable globale dans différents processus. Une fois que le processus a obtenu l'état de la variable, il utilise des conditions de jugement pour contrôler l'exécution de la logique ; transférer des variables. Voici une seule idée. Prenez memcached comme exemple
$p_file = "locktest.txt";
$o_file = fopen($p_file, 'w+');

// 如果临时文件被锁定,这里的flock()将返回false
if (!flock($o_file, LOCK_EX + LOCK_NB)) {
  var_dump('Process Locked');
}
else {
  // 非阻塞模型必须在flock()中增加LOCK_NB参数
  // 当然,这里取消LOCK_NB参数就是阻塞模型了
  flock($o_file, LOCK_EX + LOCK_NB);
  var_dump('Process Locking');
  // 模拟长时间的执行操作
  sleep(10);
}

Démo du modèle de blocage :


Ce qui doit être noté ici est :

// 初始化memcached
$memcached = new Memcache;
$memcached->connect("localhost", 11211);

// 获取用来做状态判定的全局变量
$s_flag = $memcached->get("flag");

if (!$s_flag) {
  // 这里利用了memcached的过期时间作为演示,实际上业务处理完成后销毁该变量即可
  $memcached->set("flag", "locked", 0, 10);
  main();
}
else {
  // 阻塞模型
  while ($s_flag == 'locked') {
    var_dump('Process locked, retrying...');
    // 设置重试时间, 避免过于频繁的操作尝试
    sleep(1);
    // 更新状态变量
    $s_flag = $memcached->get("flag");
  }
  // // 非阻塞模型
  // if ($s_flag == 'locked') {
  //   var_dump('Process locked, suspended');
  //   die();
  // }
  main();
}

// 模拟业务主函数
function main() {
  var_dump('Process Running');
  // 业务执行结束后回收memcached
  // $memcached->delete("flag");
}
1. Le délai d'expiration de memcached n'est pas autorisé. Il est inférieur au temps réel d'exécution du programme, il est donc recommandé d'être légèrement plus long et de recycler une fois l'exécution logique terminée


2. Dans le modèle non bloquant, si le statut est jugé faux, le processus doit être terminé ou bloqué pour éviter l'exécution continue de la logique métier


3. il est nécessaire de définir un délai de nouvelle tentative, ce qui peut réduire considérablement la grande quantité de concurrence d'E/S pour memcached ;


Recommandations associées :


<.>Explication détaillée des verrous de fichiers, des verrous mutex et des verrous en lecture-écriture en PHP


Une brève introduction aux verrous de fichiers et de processus PHP

Comparez les différences entre les verrous de fichiers et les verrous de processus en PHP

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn