久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      一文了解PHP中的進(jìn)程和進(jìn)程間通信

      本篇文章帶大家了解一下PHP中的進(jìn)程和進(jìn)程間通信。有一定的參考價(jià)值,有需要的朋友可以參考一下,希望對(duì)大家有所幫助。

      一文了解PHP中的進(jìn)程和進(jìn)程間通信

      環(huán)境

      php中的進(jìn)程是以擴(kuò)展的形式來(lái)完成。通過這些擴(kuò)展,我們能夠很輕松的完成進(jìn)程的一系列動(dòng)作。

      pcntl擴(kuò)展:主要的進(jìn)程擴(kuò)展,完成進(jìn)程創(chuàng)建于等待操作。 posix擴(kuò)展:完成posix兼容機(jī)通用api,如獲取進(jìn)程id,殺死進(jìn)程等。 sysvmsg擴(kuò)展:實(shí)現(xiàn)system v方式的進(jìn)程間通信之消息隊(duì)列。 sysvsem擴(kuò)展:實(shí)現(xiàn)system v方式的信號(hào)量。 sysvshm擴(kuò)展:實(shí)現(xiàn)system v方式的共享內(nèi)存。 sockets擴(kuò)展:實(shí)現(xiàn)socket通信。 這些擴(kuò)展只能在linux/mac中使用,window下是不支持。最后建議php版本為5.5+。

      簡(jiǎn)單的例子

      一個(gè)簡(jiǎn)單的PHP多進(jìn)程例子,該例子中,一個(gè)子進(jìn)程,一個(gè)父進(jìn)程。子進(jìn)程輸出5次,退出程序。

      echo "parent progress pid:{$parentPid}n";  $childList = array();  $pid = pcntl_fork();  if ( $pid == -1) {      // 創(chuàng)建失敗      exit("fork progress error!n");  } else if ($pid == 0) {      // 子進(jìn)程執(zhí)行程序      $pid = posix_getpid();      $repeatNum = 5;      for ( $i = 1; $i <= $repeatNum; $i++) {          echo "({$pid})child progress is running! {$i} n";          $rand = rand(1,3);          sleep($rand);      }      exit("({$pid})child progress end!n");  } else {      // 父進(jìn)程執(zhí)行程序      $childList[$pid] = 1;  }  // 等待子進(jìn)程結(jié)束  pcntl_wait($status); echo "({$parentPid})main progress end!";

      完美,終于創(chuàng)建了一個(gè)子進(jìn)程,一個(gè)父進(jìn)程。完了么?沒有,各個(gè)進(jìn)程之間相互獨(dú)立的,沒有任何交集,使用范圍嚴(yán)重受到現(xiàn)在。怎么辦,哪就進(jìn)程間通信(interprogress communication)唄。

      進(jìn)程間通信(IPC)

      通常linux中的進(jìn)程通信方式有:消息隊(duì)列、信號(hào)量、共享內(nèi)存、信號(hào)、管道、socket。

      1.消息隊(duì)列

      消息隊(duì)列是存放在內(nèi)存中的一個(gè)隊(duì)列。如下代碼將創(chuàng)建3個(gè)生產(chǎn)者子進(jìn)程,2個(gè)消費(fèi)者子進(jìn)程。這5個(gè)進(jìn)程將通過消息隊(duì)列通信。

      echo "parent progress pid:{$parentPid}n";$childList = array(); // 創(chuàng)建消息隊(duì)列,以及定義消息類型(類似于數(shù)據(jù)庫(kù)中的庫(kù)) $id = ftok(__FILE__,'m'); $msgQueue = msg_get_queue($id); const MSG_TYPE = 1; // 生產(chǎn)者 function producer(){     global $msgQueue;     $pid = posix_getpid();     $repeatNum = 5;     for ( $i = 1; $i <= $repeatNum; $i++) {         $str = "({$pid})progress create! {$i}";         msg_send($msgQueue,MSG_TYPE,$str);         $rand = rand(1,3);         sleep($rand);     } } // 消費(fèi)者 function consumer(){     global $msgQueue;     $pid = posix_getpid();     $repeatNum = 6;     for ( $i = 1; $i <= $repeatNum; $i++) {         $rel = msg_receive($msgQueue,MSG_TYPE,$msgType,1024,$message);         echo "{$message} | consumer({$pid}) destroy n";         $rand = rand(1,3);         sleep($rand);     } } function createProgress($callback){     $pid = pcntl_fork();     if ( $pid == -1) {         // 創(chuàng)建失敗         exit("fork progress error!n");     } else if ($pid == 0) {         // 子進(jìn)程執(zhí)行程序         $pid = posix_getpid();         $callback();         exit("({$pid})child progress end!n");     }else{         // 父進(jìn)程執(zhí)行程序         return $pid;     } } // 3個(gè)寫進(jìn)程 for ($i = 0; $i < 3; $i ++ ) {     $pid = createProgress('producer');     $childList[$pid] = 1;     echo "create producer child progress: {$pid} n"; } // 2個(gè)寫進(jìn)程 for ($i = 0; $i < 2; $i ++ ) {     $pid = createProgress('consumer');     $childList[$pid] = 1;     echo "create consumer child progress: {$pid} n"; } // 等待所有子進(jìn)程結(jié)束 while(!empty($childList)){     $childPid = pcntl_wait($status);     if ($childPid > 0){         unset($childList[$childPid]);     } } echo "({$parentPid})main progress end!n";

      由于消息隊(duì)列去數(shù)據(jù)是,只有一個(gè)進(jìn)程能去到,所以不需要額外的鎖或信號(hào)量。

      2. 信號(hào)量與共享內(nèi)存

      信號(hào)量:是系統(tǒng)提供的一種原子操作,一個(gè)信號(hào)量,同時(shí)只有你個(gè)進(jìn)程能操作。一個(gè)進(jìn)程獲得了某個(gè)信號(hào)量,就必須被該進(jìn)程釋放掉。

      共享內(nèi)存:是系統(tǒng)在內(nèi)存中開辟的一塊公共的內(nèi)存區(qū)域,任何一個(gè)進(jìn)程都可以訪問,在同一時(shí)刻,可以有多個(gè)進(jìn)程訪問該區(qū)域,為了保證數(shù)據(jù)的一致性,需要對(duì)該內(nèi)存區(qū)域加鎖或信號(hào)量。

      以下,創(chuàng)建多個(gè)進(jìn)程修改內(nèi)存中的同一個(gè)值。

      echo "parent progress pid:{$parentPid}n"; $childList = array();  // 創(chuàng)建共享內(nèi)存,創(chuàng)建信號(hào)量,定義共享key $shm_id = ftok(__FILE__,'m'); $sem_id = ftok(__FILE__,'s'); $shareMemory = shm_attach($shm_id); $signal = sem_get($sem_id); const SHARE_KEY = 1; // 生產(chǎn)者 function producer(){     global $shareMemory;     global $signal;     $pid = posix_getpid();     $repeatNum = 5;     for ( $i = 1; $i <= $repeatNum; $i++) {         // 獲得信號(hào)量         sem_acquire($signal);                  if (shm_has_var($shareMemory,SHARE_KEY)){             // 有值,加一             $count = shm_get_var($shareMemory,SHARE_KEY);             $count ++;             shm_put_var($shareMemory,SHARE_KEY,$count);             echo "({$pid}) count: {$count}n";         }else{             // 無(wú)值,初始化             shm_put_var($shareMemory,SHARE_KEY,0);             echo "({$pid}) count: 0n";         }         // 用完釋放         sem_release($signal);                  $rand = rand(1,3);         sleep($rand);     } } function createProgress($callback){     $pid = pcntl_fork();     if ( $pid == -1) {         // 創(chuàng)建失敗         exit("fork progress error!n");     } else if ($pid == 0) {         // 子進(jìn)程執(zhí)行程序         $pid = posix_getpid();         $callback();         exit("({$pid})child progress end!n");     }else{         // 父進(jìn)程執(zhí)行程序         return $pid;     } } // 3個(gè)寫進(jìn)程 for ($i = 0; $i < 3; $i ++ ) {     $pid = createProgress('producer');     $childList[$pid] = 1;     echo "create producer child progress: {$pid} n"; } // 等待所有子進(jìn)程結(jié)束 while(!empty($childList)){     $childPid = pcntl_wait($status);     if ($childPid > 0){         unset($childList[$childPid]);     } } // 釋放共享內(nèi)存與信號(hào)量 shm_remove($shareMemory); sem_remove($signal); echo "({$parentPid})main progress end!n";

      3.信號(hào)

      信號(hào)是一種系統(tǒng)調(diào)用。通常我們用的kill命令就是發(fā)送某個(gè)信號(hào)給某個(gè)進(jìn)程的。具體有哪些信號(hào)可以在liunx/mac中運(yùn)行kill -l查看。下面這個(gè)例子中,父進(jìn)程等待5秒鐘,向子進(jìn)程發(fā)送sigint信號(hào)。子進(jìn)程捕獲信號(hào),掉信號(hào)處理函數(shù)處理。

      echo "parent progress pid:{$parentPid}n";  // 定義一個(gè)信號(hào)處理函數(shù) function sighandler($signo) {     $pid = posix_getpid();     echo "{$pid} progress,oh no ,I'm killed!n";     exit(1); }  $pid = pcntl_fork(); if ( $pid == -1) {     // 創(chuàng)建失敗     exit("fork progress error!n"); } else if ($pid == 0) {     // 子進(jìn)程執(zhí)行程序     // 注冊(cè)信號(hào)處理函數(shù)     declare(ticks=10);     pcntl_signal(SIGINT, "sighandler");     $pid = posix_getpid();     while(true){         echo "{$pid} child progress is running!n";         sleep(1);     }     exit("({$pid})child progress end!n"); }else{     // 父進(jìn)程執(zhí)行程序     $childList[$pid] = 1;     // 5秒后,父進(jìn)程向子進(jìn)程發(fā)送sigint信號(hào).     sleep(5);     posix_kill($pid,SIGINT);     sleep(5); } echo "({$parentPid})main progress end!n";

      4.管道(有名管道)

      管道是比較常用的多進(jìn)程通信手段,管道分為無(wú)名管道與有名管道,無(wú)名管道只能用于具有親緣關(guān)系的進(jìn)程間通信,而有名管道可以用于同一主機(jī)上任意進(jìn)程。這里只介紹有名管道。下面的例子,子進(jìn)程寫入數(shù)據(jù),父進(jìn)程讀取數(shù)據(jù)。

      $pipe_path = '/data/test.pipe'; if(!file_exists($pipe_path)){     if(!posix_mkfifo($pipe_path,0664)){         exit("create pipe error!");     } } $pid = pcntl_fork(); if($pid == 0){     // 子進(jìn)程,向管道寫數(shù)據(jù)     $file = fopen($pipe_path,'w');     while (true){         fwrite($file,'hello world');         $rand = rand(1,3);         sleep($rand);     }     exit('child end!'); }else{     // 父進(jìn)程,從管道讀數(shù)據(jù)     $file = fopen($pipe_path,'r');     while (true){         $rel = fread($file,20);         echo "{$rel}n";         $rand = rand(1,2);         sleep($rand);     } }

      推薦學(xué)習(xí):《PHP視頻教程》

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)