Maison  >  Article  >  développement back-end  >  Explication détaillée des exemples d'utilisation du verrouillage de fichier et du verrouillage de processus en PHP

Explication détaillée des exemples d'utilisation du verrouillage de fichier et du verrouillage de processus en PHP

黄舟
黄舟original
2017-08-08 09:18:271138parcourir

Cet article présente principalement les exemples d'utilisation du verrouillage de fichier PHP et du verrouillage de processus. L'éditeur pense que c'est assez bon, je vais donc le partager avec vous maintenant et le donner comme référence. Suivons l'éditeur et jetons un coup d'œil.

Compte tenu de l'introduction de swoole auparavant, utilisons le mécanisme serveur/client et multi-processus de swoole pour expliquer le verrouillage.

Ceci est uniquement pour PHP. Le mécanisme de verrouillage sera expliqué. Étant donné que les verrous SQL sont différents de leurs modes d'action et de leurs scénarios d'application, ils seront expliqués séparément

1. >

  • flock()

  • fclose()

  • swoole_lock()

Les scénarios d'application possibles des verrouillages de fichiers sont :

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

2. Fichiers participants I Traiter la file d'attente et le blocage artificiel de /O ;

3. Protéger le contenu du fichier dans la logique métier ;

Ce qui suit est le fichier. lock C/S mécanisme de communication Le processus de communication spécifique a été omis pour l'utilisation de ):

Client2 (le processus de communication du serveur est 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));
});

Résultat :


Le Client2 a été bloqué pendant 30 secondes et le fichier n'a été écrit qu'une seule fois jusqu'à la fin de l'exécution de Client1
$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();


Il est à noter que :

$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();
1. Qu'il s'agisse de flock() ou de swoole_lock() fournis par swoole, il existe un mécanisme pour se déverrouiller automatiquement lorsque le processus se termine, il peut donc fonctionner normalement même sans déverrouillage manuel dans la démo, voici donc le chapitre Un client exécute la fonction de pause sleep() 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 (), ne provoque jamais de problèmes futurs


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

Contrairement au verrouillage de fichiers, le verrouillage de processus n'est pas utilisé pour empêcher les E/S sur les fichiers, mais pour éviter les conséquences inattendues causées par la concurrence multi-processus. Par conséquent, il est nécessaire de mettre plusieurs processus en file d'attente. lorsqu'ils sont simultanés, c'est-à-dire bloquer 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 de verrouillage temporaire, et 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 la mémoire partagée fournie par swoole , la méthode de cache ou la méthode de communication transfère une variable globale dans différents processus une fois que le processus a obtenu le statut de. la variable, elle utilise des conditions de jugement pour contrôler l'exécution de la logique ; Il existe de nombreuses façons de transférer des variables. Voici une seule idée, qui est memcached à titre d'exemple :

modèle de blocage. démo :


$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);
}

Ce qu'il faut noter ici est :


1. ne peut pas être 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. jugé faux, le processus doit être terminé ou bloqué pour éviter la poursuite de l'exécution de la logique métier

// 初始化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");
}
3 Dans les applications pratiques, il est nécessaire de définir un temps de nouvelle tentative, qui peut être très long ; pratique Réduisez dans une large mesure une grande quantité de concurrence d'E/S pour Memcached et réduisez la pression du serveur ;

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