成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

使用 swoole_process 實現(xiàn) PHP 進程池

Andrman / 1161人閱讀

摘要:本文使用與完成一個的進程池,并且支持動態(tài)創(chuàng)建新進程。接著遍歷所有的進程,并且加入中,設置可讀事件,用于接收子進程的空閑信號。最后每隔一秒向進程投遞任務。由于只模擬了十次任務,則第十個任務完成之后在父進程中發(fā)送使所有子進程退出。

swoole_process 主要是用來代替 PHP 的 pcntl 擴展。我們知道 pcntl 是用來進行多進程編程的,而 pcntl 只提供了 fork 這樣原始的接口,容易使用錯誤,并且沒有提供進程間通信以及重定向標準輸入輸出的功能。

而 swoole_process 則提供了比 pcntl 更強大的功能,更易用的API,使PHP在多進程編程方面更加輕松。

本文使用 swoole_process 與 EventLoop 完成一個 php 的進程池,并且支持動態(tài)創(chuàng)建新進程。
EventLoop

swoole 有一個 Reactor 線程,這個線程可以說是對 epoll 模型的封裝,可以設置 read 事件和 write 事件的監(jiān)聽回調函數(shù)。

下面會用到一個函數(shù):

bool swoole_event_add(mixed $sock, mixed $read_callback, mixed $write_callback = null, int $flags = null);

參數(shù)1為一個文件描述符,包括swoole_client->$sockswoole_process->$pipe或者其他 fd(socket_create 創(chuàng)建的資源 , stream_socket_client/fsockopen創(chuàng)建的資源)

參數(shù)2為可讀事件回調函數(shù)

參數(shù)3為可寫事件回調函數(shù)

多進程編程少不了進程之間的通訊,swoole 的進程之間有兩種通信方式,一種是消息隊列(queue),另一種是管道(pipe)。那么本文使用的是 pipe 的方式。

下面是一個定時向進程池投遞任務的例子。

代碼:

process = new swoole_process(array($this, "run"), false, 2);
        $this->process->start();
        swoole_process::wait();
    }

    public function run()
    {
        $this->current_num = $this->min_worker_num;
        //創(chuàng)建所有的worker進程
        for($i = 0; $i < $this->current_num; $i++){
            $process = new swoole_process(array($this, "task_run"), false, 2);
            $pid = $process->start();
            $this->process_list[$pid] = $process;
            $this->process_use[$pid] = 0;
        }

        foreach($this->process_list as $process){
            swoole_event_add($process->pipe, function ($pipe) use ($process){
                $data = $process->read();
                var_dump($data . "空閑");
                //接收子進程處理完成的信息,并且重置為空閑
                $this->process_use[$data] = 0;
            });
        }

        //每秒定時向worker管道投遞任務
        swoole_timer_tick(1000 ,function ($timer_id){
            static $index = 0;
            $index = $index + 1;
            $flag = true; //是否新建worker
            foreach ($this->process_use as $pid => $used){
                if($used == 0){
                    $flag = false;
                    //標記為正在使用
                    $this->process_use[$pid] = 1;
                    // 在父進程內調用write,子進程可以調用read接收此數(shù)據(jù)
                    $this->process_list[$pid]->write($index. "hello");
                    break;
                }
            }

            if($flag && $this->current_num < $this->max_worker_num){
                //沒有閑置worker,新建worker來處理
                $process = new swoole_process(array($this, "task_run"), false, 2);
                $pid = $process->start();
                $this->process_list[$pid] = $process;
                $this->process_use[$pid] = 1;
                $this->process_list[$pid]->write($index. "hello");
                $this->current_num++;
            }
            var_dump("第" .$index. "個任務");
            if($index == 10){
                foreach($this->process_list as $process){
                    $process->write("exit");
                }
                swoole_timer_clear($timer_id);
                $this->process->exit();
            }

        });
    }

    /**
     * 子進程處理
     * @param $worker
     */
    public function task_run($worker)
    {
        swoole_event_add($worker->pipe, function($pipe)use($worker){
            $data = $worker->read();
            var_dump($worker->pid . ":" . $data);
            if($data == "exit"){
                $worker->exit();
                exit;
            }
            //模擬耗時任務
            sleep(5);
            //告訴主進程處理完成
            //在子進程內調用write,父進程可以調用read接收此數(shù)據(jù)
            $worker->write($worker->pid);
        });
    }

}

new ProcessPool();

首先定義幾個重要的屬性:

$process_list :Worker 進程數(shù)組

$process_use:正在被使用的進程

$min_worker_num :最少進程數(shù)量

$max_worker_num :最多進程數(shù)量

$current_num :當前進程數(shù)量

$process : 主進程

在實例化的時候創(chuàng)建主進程,并且運行 run 方法,在 run 方法里面先創(chuàng)建所有的 worker 進程,并且設置為空閑狀態(tài)。

接著遍歷所有的 worker 進程,并且加入 EventLoop 中,設置可讀事件,用于接收子進程的空閑信號。

最后每隔一秒向 worker 進程投遞任務。動態(tài)擴充進程池則在這里實現(xiàn),如果沒有閑置的進程,而此時又有新的任務,則需要動態(tài)創(chuàng)建一個新的進程并且置為繁忙狀態(tài)。由于只模擬了十次任務,則第十個任務完成之后在父進程中發(fā)送 exit 使所有子進程退出。

運行效果與圖解:

參考鏈接:

https://wiki.swoole.com/wiki/...
https://opso.coding.me/2018/0...

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://m.hztianpu.com/yun/29584.html

相關文章

  • Swoole 源碼分析——進程管理 Swoole_Process

    摘要:清空主進程殘留的定時器與信號。設定為執(zhí)行回調函數(shù)如果在回調函數(shù)中調用了異步系統(tǒng),啟動函數(shù)進行事件循環(huán)。因此為了區(qū)分兩者,規(guī)定并不允許兩者同時存在。 前言 swoole-1.7.2 增加了一個進程管理模塊,用來替代 PHP 的 pcntl 擴展。 PHP自帶的pcntl,存在很多不足,如 pcntl 沒有提供進程間通信的功能 pcntl 不支持重定向標準輸入和輸出 pcntl 只...

    pepperwang 評論0 收藏0
  • PHP進程系列筆記(五)

    摘要:消息隊列更常見的用途是主進程分配任務,子進程消費執(zhí)行。子進程前面加了個,這是為了防止父進程還未往消息隊列中加入內容直接退出。 前面幾節(jié)都是講解pcntl擴展實現(xiàn)的多進程程序。本節(jié)給大家介紹swoole擴展的swoole_process模塊。 swoole多進程 swoole_process 是swoole提供的進程管理模塊,用來替代PHP的pcntl擴展。 首先,確保安裝的swoole...

    qianfeng 評論0 收藏0
  • Swoole筆記(一)

    摘要:修復添加超過萬個以上定時器時發(fā)生崩潰的問題增加模塊,下高性能序列化庫修復監(jiān)聽端口設置無效的問題等。線程來處理網(wǎng)絡事件輪詢,讀取數(shù)據(jù)。當?shù)娜挝帐殖晒α艘院?,由這個線程將連接成功的消息告訴進程,再由進程轉交給進程。此時進程觸發(fā)事件。 本文示例代碼詳見:https://github.com/52fhy/swoo...。 簡介 Swoole是一個PHP擴展,提供了PHP語言的異步多線程服務器...

    SHERlocked93 評論0 收藏0
  • Swoole 4.0 正式版,面向生產(chǎn)環(huán)境的 PHP 協(xié)程引擎

    摘要:在禁止場景中使用協(xié)程會出現(xiàn)各種莫名其妙的問題發(fā)生。限制了協(xié)程的應用范圍。新版本基于匯編代碼實現(xiàn)了全新的協(xié)程內核。實現(xiàn)了對所有語法的支持。穩(wěn)定性和健壯性均已達到工業(yè)級的水準。完全可用于大型項目的生產(chǎn)環(huán)境中。 Swoole雖然在2016年就支持了協(xié)程特性,但由于底層是基于setjmp/longjmp實現(xiàn)的stackless方案。因此在某些場景下,如call_user_func、array_...

    Zack 評論0 收藏0

發(fā)表評論

0條評論

Andrman

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<