基於PCNTl擴充套件的PHP多程式管理庫

slince發表於2019-02-16

大多數人都說php是單程式執行的,其實這是不準確的,在cli模式下php是可以做到多程式的;不過需要pcntl的擴充套件;

$pid = pcntl_fork();
//父程式和子程式都會執行下面程式碼
if ($pid == -1) {
    //錯誤處理:建立子程式失敗時返回-1.
     die(`could not fork`);
} else if ($pid) {
     //父程式會得到子程式號,所以這裡是父程式執行的邏輯
     pcntl_wait($status); //等待子程式中斷,防止子程式成為殭屍程式。
} else {
     //子程式得到的$pid為0, 所以這裡是子程式執行的邏輯。
}

上面的程式碼摘自php官方手冊,熟悉C語言的同學可能很吃驚,簡直跟c的api是一毛一樣的;確實是這樣,一樣直白,一樣沒有包裝;現在這種問題得到解決了;先附上鍊接https://github.com/slince/process

通過composer安裝

composer require slince/process

基本用法

//建立子程式
$process = new SlinceProcessProcess(function(){
    echo `hello, my pid is ` . getmypid();
});
$process->start(); //程式執行到此處發生分裂,下面的程式碼在父程式執行,上面閉包的程式碼在子程式執行

var_dump($process->isRunning()); // 子程式是否還在執行
var_dump($process->getPid()); // 獲取子程式id

//其他業務邏輯

$process->wait(); //等待子程式執行完畢,此過程會發生阻塞;不要忘了此步驟

註冊新號處理器,以及觸發新號

$process = ...
$process->getSignalHandler()->register([SIGUSR1, SIGUSR2], function(){
    echo `trigger signal`;
});
$process->start();
$process->signal(SIGUSER1); //給子程式發訊號
$process->wait();

其它IPC包裝

Shared memory

$memory = new SlinceProcessSystemVSharedMemory();
$memory->set(`foo`, `bar`);
var_dump($memory->get(`foo`));

The default size of shared memory is the sysvshm.init_mem in the php.ini, otherwise 10000 bytes. You can adjust this.

$memory = new SlinceProcessSystemVSharedMemory(__FILE__, `5M`); //Adjusts to 5m

Semaphore

$semaphore = new SlinceProcessSystemVSemaphore();
$semaphore->acquire(); //Acquires a lock
// do something
$semaphore->release() //Releases a lock

Message queue

$queue  = new SlinceProcessSystemVMessageQueue();
$queue->send(`hello`);
echo $queue->receive(); //Will output hello

Fifo

$writeFifo = new SlinceProcessPipeWritableFifo(`/tmp/test.pipe`);
$writeFifo->write(`some message`);
$readFifo = new SlinceProcessPipeReadableFifo(`/tmp/test.pipe`);
echo $readFifo->read();

Fifo works with half duplex mode. You can use DuplexFifo that will create two fifos.

$fifo = new SlinceProcessPipeDuplexFifo(`/tmp/test.pipe`);
$fifo->write(`some message`);
$fifo->read();

由於pcntl擴充套件在window上是不可用的,所以本庫並不能在window上使用;如果有需求的化建議使用symfony/process但需要注意的是該庫只能實現程式間呼叫,也就是說你必須先建立一個指令碼命令再呼叫該命令,與pcntl擴充套件實現的並不是同一個東西。

最後再次附上專案地址https://github.com/slince/process 歡迎star

相關文章