Maison  >  Article  >  développement back-end  >  PHP implémente le verrouillage de fichier et le verrouillage de processus

PHP implémente le verrouillage de fichier et le verrouillage de processus

墨辰丷
墨辰丷original
2018-05-18 15:46:311988parcourir

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 pour y jeter un œil

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. Mise en file d'attente et blocage artificiel des processus participant aux E/S de fichiers ;

3. Protégez le contenu du fichier 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 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));
});

Client1 (le processus de communication du serveur est 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 :


Le Client2 a été bloqué pendant 30 secondes et le fichier n'a été écrit qu'une seule fois avant la fin de l'exécution du Client1 ;

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

Il convient de le noter que :

1. Qu'il s'agisse de flock() ou de swoole_lock() fournis par swoole, il existe un mécanisme pour se déverrouiller automatiquement à la fin du processus, afin qu'il puisse fonctionner normalement même sans déverrouillage manuel dans la démo, donc voici le chapitre Un client exécute la fonction de pause sleep() pour observer l'effet du verrouillage de fichier


2. La méthode de libération standard de flock() est flock($file, LOCK_UN);, mais personnellement, j'aime fclose (), ne cause jamais de problèmes futurs


2. Verrouillage du processus

Différent du verrouillage des fichiers, processus ; le verrouillage n'est pas utilisé pour empêcher les E/S sur les fichiers est utilisé pour éviter les conséquences inattendues causées par la concurrence multi-processus. Par conséquent, il est nécessaire de mettre en file d'attente plusieurs processus lorsqu'ils sont simultanés, c'est-à-dire de bloquer d'autres processus simultanés avant l'exécution de la logique clé. d'un processus se termine. Exécution logique.

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 utiliser 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 :

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

2. Utilisez swoole pour fournir La mémoire partagée, la méthode de mise en cache ou la méthode de communication transmettent 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 logique ;

Il existe de nombreuses façons de transmettre des variables, voici une seule idée, prenez Memcached comme exemple

Démo du modèle de blocage :

// 初始化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");
}
Ce qu'il faut noter ici est :

1. Le délai d'expiration de memcached ne peut pas être inférieur au temps réel d'exécution du programme, il est donc nécessaire de le noter. il est 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 l'état est jugé faux, le processus doit être suspendu ou bloqué pour éviter l'exécution continue de la logique métier ;


3. Dans les applications réelles, il est très difficile de définir un délai de nouvelle tentative si nécessaire, cela peut réduire considérablement la concurrence d'E/S. memcached et réduire la pression du serveur ;



Recommandations associées :


La mise en œuvre de PHP est basée sur le

File Lock

Pour résoudre le problème de plusieurs processus lisant et écrivant un fichier en même temps

php
File Lock

Pour résoudre le problème de la haute concurrence

Explication détaillée des étapes pour résoudre la concurrence élevée en PHP à l'aide de
File Lock


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