免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
【Swoole系列4.3】協(xié)程操作系統(tǒng)API

協(xié)程操作系統(tǒng)API

學(xué)習(xí)完核心的協(xié)程相關(guān)操作 API 之后,我們?cè)賮?lái)看看協(xié)程可以操作的系統(tǒng)相關(guān)的 API 函數(shù)。其實(shí)也都是一些非常簡(jiǎn)單的功能,系統(tǒng)相關(guān)的調(diào)用無(wú)外乎就是操作文件、進(jìn)程之類的功能,不過(guò)在協(xié)程中,它們的應(yīng)用可能會(huì)略有不同。我們一個(gè)一個(gè)的來(lái)看一下。

休息和調(diào)用方法

首先就是我們非常熟悉的 sleep() 。

\Swoole\Coroutine\run(function(){
   go(function(){
       co::sleep(2);
       echo "cid:" . Co::getCid() , PHP_EOL;
   });

   go(function(){
       \Swoole\Coroutine\System::sleep(2);
       echo "cid:" . Co::getCid() , PHP_EOL;
   });

   go(function(){
       echo "cid:" . Co::getCid() , PHP_EOL;
       $ret = \Swoole\Coroutine\System::exec("ls -l ./");
       var_dump($ret);
   });
});

我們可以使用 co::sleep() ,這也是之前測(cè)試中最常用的一咱寫(xiě)法。但其實(shí)更標(biāo)準(zhǔn)的寫(xiě)法是 \Swoole\Coroutine\System::sleep() 或者 Co\System::sleep() 。在新的版本中,為了規(guī)范命名空間,今天所講的內(nèi)容盡量去使用 System 相關(guān)的命名空間類來(lái)使用,但是,為了向下兼容,之前的寫(xiě)法也是可以的。

關(guān)于 sleep() 之前我們也講過(guò)了,它在內(nèi)部其實(shí)就是實(shí)現(xiàn)了 yield() 和 resume() 的調(diào)度。在這里我們也不多說(shuō)了,還不太了解的小伙伴可以仔細(xì)看一下上一篇文章中我們學(xué)習(xí)過(guò)的相關(guān)知識(shí)。

另一個(gè)方法 exec() 則是執(zhí)行一個(gè)外部程序。這個(gè)想必也不用過(guò)多地解釋了。上面的測(cè)試代碼輸出的結(jié)果應(yīng)該是下面這樣的。

//cid:4
//array(3) {
//    ["code"]=>
//  int(0)
//  ["signal"]=>
//  int(0)
//  ["output"]=>
//  string(222) "total 16
//-rw-r--r--. 1 root root 3509 Dec 20 21:50 4.1Swoole協(xié)程服務(wù).php
//-rw-r--r--. 1 root root 6704 Dec 27 22:57 4.2協(xié)程應(yīng)用與容器.php
//-rw-r--r--. 1 root root  416 Dec 28 20:05 4.3協(xié)程操作系統(tǒng)API.md.php
//"
//}
//cid:2
//cid:3

進(jìn)程回收等待

進(jìn)程回收等待還記得是啥嘛?在進(jìn)程篇章中,我們幾乎所有的測(cè)試代碼都會(huì)用到,就是那個(gè) Process::wait() 。它用于等待子進(jìn)程完成并回收,避免產(chǎn)生僵尸進(jìn)程。

在協(xié)程中,也有類似的方法,可以在協(xié)程環(huán)境下進(jìn)行進(jìn)程的等待回收,效果也是一樣的,為了避免出現(xiàn)僵尸進(jìn)程浪費(fèi)系統(tǒng)資源。

$process = new \Swoole\Process(function(){
   echo "Process";
});
$process->start();
echo "進(jìn)程 pid: ". $process->pid, PHP_EOL;

\Swoole\Coroutine\run(function(){
   $status = \Swoole\Coroutine\System::wait();
   echo "wait 進(jìn)程 pid: ".$status['pid'], PHP_EOL;
   var_dump($status);
});
//進(jìn)程 pid: 1489
//Processwait 進(jìn)程 pid: 1489
//array(3) {
//    ["pid"]=>
//  int(1489)
//  ["code"]=>
//  int(0)
//  ["signal"]=>
//  int(0)
//}

$process1 = new \Swoole\Process(function(){
});
$process1->start();
echo "進(jìn)程1 pid: ". $process1->pid, PHP_EOL;

$process2 = new \Swoole\Process(function(){
   sleep(5);
});
$process2->start();
echo "進(jìn)程2 pid: ". $process2->pid, PHP_EOL;

\Swoole\Coroutine\run(function() use ($process1){
   $status = \Swoole\Coroutine\System::waitPid($process1->pid);
   echo "waitPid 進(jìn)程 pid: ".$status['pid'], PHP_EOL;
   var_dump($status);

   $status = \Swoole\Coroutine\System::wait();
   echo "wait 進(jìn)程 pid: ".$status['pid'], PHP_EOL;
   var_dump($status);

});
//進(jìn)程1 pid: 1491
//進(jìn)程2 pid: 1492
//waitPid 進(jìn)程 pid: 1491
//array(3) {
//    ["pid"]=>
//  int(1491)
//  ["code"]=>
//  int(0)
//  ["signal"]=>
//  int(0)
//}
//wait 進(jìn)程 pid: 1492
//array(3) {
//    ["pid"]=>
//  int(1492)
//  ["code"]=>
//  int(0)
//  ["signal"]=>
//  int(0)
//}

除了普通的 wait() 之外,還有一個(gè) waitPid() 方法,可以指定只回收指定 pid 的進(jìn)程。這個(gè)功能在進(jìn)程模塊相關(guān)的方法中好像是沒(méi)有的。

另外,我們?cè)趨f(xié)程中也可以監(jiān)聽(tīng)信號(hào),也就是和 Process::signal() 一樣的功能。

$process = new \Swoole\Process(function () {
   \Swoole\Coroutine\run(function () {
       $bool = \Swoole\Coroutine\System::waitSignal(SIGUSR1);
       var_dump($bool);
   });
});
$process->start();
sleep(1);
$process::kill($process->pid, SIGUSR1);

//[root@localhost source]# php 4.3協(xié)程操作系統(tǒng)API.md.php
//[root@localhost source]# bool(true)

域名操作

域名操作主要就是返回對(duì)應(yīng)的域名 ip 信息。

\Swoole\Coroutine\run(function(){
   $ip = Swoole\Coroutine\System::gethostbyname("www.baidu.com", AF_INET, 0.5);
   echo $ip, PHP_EOL;

   $ip = Swoole\Coroutine\System::dnsLookup("www.baidu.com");
   echo $ip, PHP_EOL;

   $ips = Swoole\Coroutine\System::getaddrinfo("www.baidu.com");
   var_dump($ips);
});
//112.80.248.75
//112.80.248.76
//array(2) {
//    [0]=>
//  string(13) "112.80.248.75"
//    [1]=>
//  string(13) "112.80.248.76"
//}

gethostbyname() 基于 libc 的 gethostbyname() 實(shí)現(xiàn),將指定域名解析為 IP 。dnsLookup() 是另一種域名對(duì)應(yīng) IP 的查詢方式,它不是基于 gethostbyname() 的。getaddrinfo() 進(jìn)行 DNS 解析,通過(guò) DNS 信息查詢對(duì)應(yīng)域名的 IP 地址。

關(guān)于這三個(gè)函數(shù),可以查詢一下 C 語(yǔ)言中相關(guān)的資料,也可以了解一下網(wǎng)絡(luò)相關(guān)的知識(shí)。

文件操作

文件操作就是對(duì)文件進(jìn)行讀寫(xiě)操作,和我們普通的 PHP 開(kāi)發(fā)沒(méi)什么區(qū)別,只是說(shuō)調(diào)用 System 的方法是實(shí)現(xiàn)了協(xié)程版本的。

$file = __DIR__ . "/test.data";
$fp = fopen($file, "a+");
Swoole\Coroutine\run(function () use ($fp, $file)
{
   $r = Swoole\Coroutine\System::fwrite($fp, "hello world\n" . PHP_EOL, 5);
   var_dump($r);

   var_dump(\Swoole\Coroutine\System::readFile($file));
});
//int(5)
//string(5) "hello"

Swoole\Coroutine\run(function () use ($fp, $file)
{
   \Swoole\Coroutine\System::writeFile($file, "happy new year\n", FILE_APPEND);

   $r = Swoole\Coroutine\System::fread($fp);
   var_dump($r);

   while($r = Swoole\Coroutine\System::fgets($fp)){
       var_dump($r);
   }
});
//string(15) "happy new year
//"
//string(20) "hellohappy new year
//"

兩段測(cè)試代碼,但我們都用了不同的方式來(lái)讀寫(xiě)。第一段代碼中,使用的是 System::fwrite() 來(lái)寫(xiě)入文件,注意它可以指定寫(xiě)入大小,很明顯,我們這一行代碼只能寫(xiě)進(jìn)去 5 個(gè)字符。然后,在這個(gè)協(xié)程容器中,通過(guò) System::readFile() 來(lái)讀取整個(gè)文件。

第二段協(xié)程容器中,我們先使用 System::writeFile() 來(lái)向文件中追加內(nèi)容,它就不是流式寫(xiě)入了,直接會(huì)把內(nèi)容全部寫(xiě)進(jìn)去,所以文件當(dāng)前的內(nèi)容是 "hellohappy new year\n" 。接著,我們使用 fread() 的方式讀取文件,它也是可以指定讀取長(zhǎng)度的,不填的話就是全部讀取。

最后,我們還使用了 System::fgets() ,和普通的 File 操作函數(shù)中的 fgets() 一樣,它也是按行讀取數(shù)據(jù)的。

其實(shí)這幾個(gè)方法函數(shù)和普通模式下的文件操作相關(guān)的函數(shù)差不多,而且最主要的是,后面我們學(xué)習(xí)了一鍵協(xié)程化了之后,其實(shí)根本不用這些函數(shù)了,直接通過(guò)一鍵協(xié)程化就可以讓普通的 PHP 函數(shù)以協(xié)程方式運(yùn)行。感覺(jué)很嗨吧?我們?cè)趨f(xié)程篇最后才會(huì)說(shuō)這個(gè)東西,不急哦。

進(jìn)程交互通信

由于在協(xié)程空間內(nèi) fork 進(jìn)程會(huì)帶著其他協(xié)程上下文,因此底層禁止了在 Coroutine 中使用 Process 模塊??梢允褂茫?/p>

  • System::exec() 或 Runtime Hook+shell_exec 實(shí)現(xiàn)外面程序運(yùn)行

  • Runtime Hook+proc_open 實(shí)現(xiàn)父子進(jìn)程交互通信

上面這段是官網(wǎng)的原文,意思嘛很明顯,沒(méi)事別讓協(xié)程和進(jìn)程通信。如果要通信,使用 Table 之類的方案唄。System::exec() 的例子上面已經(jīng)演示過(guò)了,官網(wǎng)上的例子實(shí)現(xiàn)的就是第二個(gè)進(jìn)程交互通信,我也不再敲了,直接粘過(guò)來(lái)。

// main.php
use Swoole\Runtime;
use function Swoole\Coroutine\run;

Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
run(function () {
    $descriptorspec = array(
        0 => array("pipe""r"),
        1 => array("pipe""w"),
        2 => array("file""/tmp/error-output.txt""a")
    );

    $process = proc_open('php ' . __DIR__ . '/read_stdin.php', $descriptorspec, $pipes);

    $n = 10;
    while ($n--) {
        fwrite($pipes[0], "hello #$n \n");
        echo fread($pipes[1], 8192);
    }

    fclose($pipes[0]);
    proc_close($process);
});

// read_stdin.php
while(true) {
    $line = fgets(STDIN);
    if ($line) {
        echo $line;
    } else {
        break;
    }
}

官網(wǎng)例子的意思就是通過(guò)Runtime Hook(一鍵協(xié)程化)的 proc_open() 函數(shù)打開(kāi)另一個(gè) PHP 腳本 read_stdin.php ,也就是一個(gè)新的進(jìn)程,這個(gè)腳本持續(xù)掛起并獲得 STDIN 輸入流的內(nèi)容,然后 main.php 這邊就可以通過(guò)輸入輸出流進(jìn)行數(shù)據(jù)寫(xiě)入將數(shù)據(jù)傳給 read_stdin.php ,從而最終實(shí)現(xiàn)了兩個(gè)進(jìn)程的通信。

總結(jié)

今天的內(nèi)容比較簡(jiǎn)單也比較好理解吧,沒(méi)有什么特別難的地方,只是函數(shù)方法的使用而已。其實(shí)我們用得最多的就只是 System::sleep() ,注意,以后新項(xiàng)目就盡量這么寫(xiě)吧,萬(wàn)一哪天 co::sleep() 的寫(xiě)法就會(huì)被標(biāo)記為過(guò)時(shí)了呢。

下篇文章,我們將學(xué)習(xí)協(xié)程間的通信工具 Channel 模塊的使用。

測(cè)試代碼:

https://github.com/zhangyue0503/swoole/blob/main/4.Swoole%E5%8D%8F%E7%A8%8B/source/4.3%E5%8D%8F%E7%A8%8B%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9FAPI.php

參考文檔:

https://wiki.swoole.com/#/coroutine/system

https://wiki.swoole.com/#/coroutine/proc_open

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
(1)swoole教程第一節(jié):進(jìn)程管理模塊(Process)
PHP多進(jìn)程編程【轉(zhuǎn)】
要學(xué)swoole看這個(gè) 比看文檔強(qiáng)多了 (文末有福利)
進(jìn)程監(jiān)控
Swoole
在PHP中靈活使用foreach+list處理多維數(shù)組
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服