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
À 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); }
// 初始化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"); }
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
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!