日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

swoole的process模块创建和使用子进程

發(fā)布時(shí)間:2024/4/14 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 swoole的process模块创建和使用子进程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

swoole中為我們提供了一個(gè)進(jìn)程管理模塊 Process,替換PHP的 pcntl 擴(kuò)展,方便我們創(chuàng)建進(jìn)程,管理進(jìn)程,和進(jìn)程間的通信。

swoole提供了2種進(jìn)程間的通信:

1、基于 unix socket 的管道 pipe。

2、基于 sysvmsg 的消息隊(duì)列。

我們可以通過(guò) new swoole_process() 快速的創(chuàng)建一個(gè)進(jìn)程,默認(rèn)會(huì)創(chuàng)建一個(gè)?SOCK_DGRAM 類型的管道,用于進(jìn)程間的通信,當(dāng)然可以設(shè)置成其他類型,也可以不創(chuàng)建。

一、通過(guò)同步阻塞管道進(jìn)行進(jìn)程間通信

<?php$worker_process_nums = 5; $worker_process = [];for ($i = 0; $i < $worker_process_nums; $i++) {//創(chuàng)建子進(jìn)程//默認(rèn)為每個(gè)子進(jìn)程創(chuàng)建一個(gè)管道,如果不想創(chuàng)建設(shè)置$pipe_type參數(shù)為false//注意管道默認(rèn)是同步阻塞,半雙工,如果讀取不到數(shù)據(jù)就會(huì)阻塞$worker = new swoole_process(function (swoole_process $worker) {//注意,如果主進(jìn)程中不寫(xiě)數(shù)據(jù)write(),那么子進(jìn)程這里read()就會(huì)阻塞$task = json_decode($worker->read(), true);//進(jìn)行計(jì)算任務(wù)$tmp = 0;for ($i = $task['start']; $i < $task['end']; $i++) {$tmp += $i;}echo '子進(jìn)程 PID : ', $worker->pid, ' 計(jì)算 ', $task['start'], ' - ', $task['end'], ' 結(jié)果 : ', $tmp, PHP_EOL;//往管道中寫(xiě)入計(jì)算的結(jié)果$worker->write($tmp);//子進(jìn)程退出$worker->exit();});//保存子進(jìn)程$worker_process[$i] = $worker;//啟動(dòng)子進(jìn)程$worker->start(); }//往每個(gè)子進(jìn)程管道中投遞任務(wù) for ($i = 0; $i < $worker_process_nums; $i++) {$worker_process[$i]->write(json_encode(['start' => mt_rand(1, 10),'end' => mt_rand(50, 100),])); }//父進(jìn)程監(jiān)聽(tīng)子進(jìn)程退出信號(hào),回收子進(jìn)程,防止出現(xiàn)僵尸進(jìn)程 swoole_process::signal(SIGCHLD, function ($sig) {//必須為false,非阻塞模式while ($ret = swoole_process::wait(false)) {echo "子進(jìn)程 PID : {$ret['pid']} 退出\n";} });

  

二、通過(guò)?swoole_event_add 將管道設(shè)為異步,來(lái)進(jìn)行通信

<?php$worker_process_nums = 5; $worker_process = [];for ($i = 0; $i < $worker_process_nums; $i++) {$worker = new swoole_process(function ($worker) {//在子進(jìn)程中給管道添加事件監(jiān)聽(tīng)//底層會(huì)自動(dòng)將該管道設(shè)置為非阻塞模式//參數(shù)二,是可讀事件回調(diào)函數(shù),表示管道可以讀了swoole_event_add($worker->pipe, function ($pipe) use ($worker) {$task = json_decode($worker->read(), true);$tmp = 0;for ($i = $task['start']; $i < $task['end']; $i++) {$tmp += $i;}echo "子進(jìn)程 : {$worker->pid} 計(jì)算 {$task['start']} - {$task['end']} \n";//子進(jìn)程把計(jì)算的結(jié)果,寫(xiě)入管道$worker->write($tmp);//注意,swoole_event_add與swoole_event_del要成對(duì)使用swoole_event_del($worker->pipe);//退出子進(jìn)程$worker->exit();});});$worker_process[$i] = $worker;//啟動(dòng)子進(jìn)程$worker->start(); }for ($i = 0; $i < $worker_process_nums; $i++) {$worker = $worker_process[$i];$worker->write(json_encode(['start' => mt_rand(1, 10),'end' => mt_rand(50, 100),]));//主進(jìn)程中,監(jiān)聽(tīng)子進(jìn)程管道事件swoole_event_add($worker->pipe, function ($pipe) use ($worker) {$result = $worker->read();echo "子進(jìn)程 : {$worker->pid} 計(jì)算結(jié)果 {$result} \n";swoole_event_del($worker->pipe);}); }//父進(jìn)程監(jiān)聽(tīng)子進(jìn)程退出信號(hào),回收子進(jìn)程,防止出現(xiàn)僵尸進(jìn)程 swoole_process::signal(SIGCHLD, function ($sig) {//必須為false,非阻塞模式while ($ret = swoole_process::wait(false)) {echo "子進(jìn)程 PID : {$ret['pid']} 退出\n";} });

  

三、使用消息隊(duì)列來(lái)完成進(jìn)程間通信

<?php$worker_process_nums = 5; $worker_process = [];for ($i = 0; $i < $worker_process_nums; $i++) {//注意,這里將參數(shù)$pipe_type設(shè)為false,表示不創(chuàng)建管道$worker = new swoole_process(function ($worker) {$task = json_decode($worker->pop(), true);$tmp = 0;for ($i = $task['start']; $i < $task['end']; $i++) {$tmp += $i;}echo "子進(jìn)程 : {$worker->pid} 計(jì)算 {$task['start']} - {$task['end']} \n";$worker->push($tmp);$worker->exit();}, false, false);//使用消息隊(duì)列,作為進(jìn)程間的通信//注意,消息隊(duì)列是共享的$worker->useQueue();$worker_process[$i] = $worker;//啟動(dòng)子進(jìn)程$worker->start(); }for ($i = 0; $i < $worker_process_nums; $i++) {//只需用一個(gè)子進(jìn)程發(fā)送消息即可,因?yàn)橄㈥?duì)列是共享的$worker_process[0]->push(json_encode(['start' => mt_rand(1, 10),'end' => mt_rand(50, 100),])); }//注意,這里要暫停,防止加入隊(duì)列的任務(wù),立刻被主進(jìn)程讀出來(lái)。 sleep(1);for ($i = 0; $i < $worker_process_nums; $i++) {$result = $worker_process[0]->pop();echo "計(jì)算結(jié)果 : {$result} \n"; }//父進(jìn)程監(jiān)聽(tīng)子進(jìn)程退出信號(hào),回收子進(jìn)程,防止出現(xiàn)僵尸進(jìn)程 swoole_process::signal(SIGCHLD, function ($sig) {//必須為false,非阻塞模式while ($ret = swoole_process::wait(false)) {echo "子進(jìn)程 PID : {$ret['pid']} 退出\n";} });

  

四、進(jìn)程可以通過(guò) signal 監(jiān)聽(tīng)信號(hào),和?alarm 設(shè)置定時(shí)器。

我們可以在父進(jìn)程上設(shè)置監(jiān)聽(tīng)信號(hào),當(dāng)子進(jìn)程退出時(shí),重新掛起子進(jìn)程。

也可以設(shè)置定時(shí)器,通過(guò) swoole_process::kill($pid, 0); 定時(shí)檢測(cè)進(jìn)程是否存活。

<?php//每隔1秒觸發(fā)SIGALAM信號(hào) //注意,alarm不能和Timer同時(shí)使用 swoole_process::alarm(1000 * 1000, 0);swoole_process::signal(SIGALRM, function ($signo) {static $cnt = 0;$cnt++;echo "時(shí)鐘定時(shí)信號(hào)\n";if ($cnt > 10) {//清除定時(shí)器swoole_process::alarm(-1);} });swoole_process::signal(SIGINT, function ($signo) {echo "我被ctrl+c了\n";//退出主進(jìn)程,不然將一直無(wú)法正常退出exit(0); });

  

轉(zhuǎn)載于:https://www.cnblogs.com/jkko123/p/10918056.html

總結(jié)

以上是生活随笔為你收集整理的swoole的process模块创建和使用子进程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。