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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > php >内容正文

php

PHP 进程的实现与管理

發(fā)布時(shí)間:2025/3/18 php 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP 进程的实现与管理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

應(yīng)用場景

一些耗時(shí)任務(wù):

  • 大數(shù)據(jù)表分表后的統(tǒng)計(jì)信息功能
  • 分批發(fā)送短信或郵件功能
  • 其他可分目標(biāo)的任務(wù)功能(很多種)
  • 所以我們就需要一個(gè)常駐內(nèi)存的任務(wù)管理工具,為了保證實(shí)時(shí)性,一方面我們讓它一直執(zhí)行任務(wù)(適當(dāng)?shù)乃?#xff0c;保證cpu不被100%占用),另一方面我們實(shí)現(xiàn)多進(jìn)程保證并發(fā)的執(zhí)行任務(wù),當(dāng)然除此之外也可按情況使用線程、協(xié)程實(shí)現(xiàn)。

    運(yùn)行模式

    實(shí)現(xiàn)PHP進(jìn)程前,需了解常見的php的運(yùn)行模式:

  • CGI通用網(wǎng)關(guān)接口模式
  • FAST-CGI模式
  • CLI命令行模式 (php xxx.php)
  • 模塊模式(作為服務(wù)器模塊)
  • 而php進(jìn)程則是使用CLI命令行模式運(yùn)行的

    基本實(shí)現(xiàn)

    PHP中提供了一個(gè)擴(kuò)展pcntl,可以利用操作系統(tǒng)的fork調(diào)用來實(shí)現(xiàn)多進(jìn)程。fork調(diào)用后執(zhí)行的代碼將是并行的,且只能在linux下運(yùn)行。

    $ppid = posix_getpid();// 獲取當(dāng)前進(jìn)程PID $pid = pcntl_fork(); //創(chuàng)建進(jìn)程switch ($pid){// 創(chuàng)建進(jìn)程錯(cuò)誤case -1:throw new Exception('fork子進(jìn)程失敗!');break;// 子進(jìn)程workercase 0:$cpid = posix_getpid();cli_set_process_title("我是{$ppid}的子進(jìn)程,我的進(jìn)程id是{$cpid}.");sleep(30);exit; // 這里exit掉,避免worker繼續(xù)執(zhí)行下面的代碼而造成一些問題break;// 主進(jìn)程masterdefault:cli_set_process_title("我是父進(jìn)程,我的進(jìn)程id是{$ppid}.");pcntl_wait($status); // 掛起父進(jìn)程,等待并返回子進(jìn)程狀態(tài),防止子進(jìn)程成為僵尸進(jìn)程break; }

    在命令行php xxx.php運(yùn)行后,使用ps aux | grep 進(jìn)程可以看到:

    如果沒看到,可能是中文亂碼了,使用ps aux,查看

    或者使用ps –ajft查看層次顯示

    進(jìn)程管理-防止進(jìn)程成為僵尸進(jìn)程

    創(chuàng)建好了進(jìn)程,那么怎么對子進(jìn)程進(jìn)行管理呢?使用信號(hào),對子進(jìn)程的管理,一般有兩種情況:
    posix_kill():此函數(shù)并不能顧名思義,它通過向子進(jìn)程發(fā)送一個(gè)信號(hào)來操作子進(jìn)程,在需要要時(shí)可以選擇給子進(jìn)程發(fā)送進(jìn)程終止信號(hào)來終止子進(jìn)程;
    pcntl_waitpid():等待或返回fork的子進(jìn)程狀態(tài),如果指定的子進(jìn)程在此函數(shù)調(diào)用時(shí)已經(jīng)退出(俗稱僵尸進(jìn)程),此函數(shù)將立刻返回,并釋放子進(jìn)程的所有系統(tǒng)資源,此進(jìn)程可以避免子進(jìn)程變成僵尸進(jìn)程,造成系統(tǒng)資源浪費(fèi);

    孤兒進(jìn)程:父進(jìn)程掛了,子進(jìn)程被pid=1的init進(jìn)程接管(wait/waitpid),直到子進(jìn)程自身生命周期結(jié)束被系統(tǒng)回收資源和父進(jìn)程 采取相關(guān)的回收操作
    僵尸進(jìn)程:子進(jìn)程exit退出,父進(jìn)程沒有通過wait/waitpid獲取子進(jìn)程狀態(tài),子進(jìn)程占用的進(jìn)程號(hào)等描述資源符還存在,產(chǎn)生危害:例如進(jìn)程號(hào)是有限的,無法釋放進(jìn)程號(hào)導(dǎo)致未來可能無進(jìn)程號(hào)可用

    **父進(jìn)程中使用:pcntl_wait或者pcntl_waitpid的目的就是防止worker成為僵尸進(jìn)程
    作用:使用pcntl_wait()后,在子進(jìn)程死掉后,父進(jìn)程也會(huì)被停止**

    最后我們通過下圖(1-1)來簡單的總結(jié)和描述這個(gè)多進(jìn)程實(shí)現(xiàn)的過程:

    進(jìn)程管理-進(jìn)程間通信

    隊(duì)列:如Redis,推薦
    socket:推薦
    管道:實(shí)現(xiàn)復(fù)雜,且管道(pipe),使用文件形式存在,存在硬盤IO性能瓶頸
    信號(hào):承載信息量少,不好管理

    進(jìn)程管理-切換為守護(hù)進(jìn)程

    使用&實(shí)現(xiàn)
    php deadloop.php &

    實(shí)際多進(jìn)程的使用

    一個(gè)耗時(shí)10S的任務(wù),執(zhí)行2次,總耗時(shí)20S,而開2個(gè)進(jìn)程,只需10S,如下:

    job.php:

    index.php(進(jìn)程開啟腳本): echo '開始時(shí)間:'.date('H:i:s', time())."\n";$cmds = [['./job.php', 0, 50000],//執(zhí)行腳本,并傳參['./job.php', 50000, 100000] ]; for ($i = 0; $i < 2; $i++){$ppid = posix_getpid();// 獲取當(dāng)前進(jìn)程PID$pid = pcntl_fork(); //創(chuàng)建進(jìn)程switch ($pid){// 創(chuàng)建進(jìn)程錯(cuò)誤case -1:throw new Exception('fork子進(jìn)程失敗!');break;// 子進(jìn)程workercase 0:$cpid = posix_getpid();cli_set_process_title("我是{$ppid}的子進(jìn)程,我的進(jìn)程id是{$cpid}.");// 執(zhí)行業(yè)務(wù)腳本pcntl_exec('/usr/local/php/bin/php', $cmds[$i]);exit; // 這里exit掉,避免worker繼續(xù)執(zhí)行下面的代碼而造成一些問題break;} }// 等待子進(jìn)程結(jié)束 while (pcntl_waitpid(0, $status) != -1) {$status = pcntl_wexitstatus($status);echo '子進(jìn)程結(jié)束時(shí)間:'.date('H:i:s', time())."\n"; }

    運(yùn)行php index.php后:

    實(shí)例達(dá)到理想效果。

    總結(jié)

    以上是生活随笔為你收集整理的PHP 进程的实现与管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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