成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PHP編程中的并發(fā)

lewinlee / 3378人閱讀

摘要:編程中的并發(fā)周末去北京面了兩個(gè)公司,認(rèn)識(shí)了幾位技術(shù)牛人,面試中聊了很多,感覺收獲頗豐。本文大約總結(jié)了編程中的五種并發(fā)方式,最后的的實(shí)現(xiàn)純屬無聊,可以無視。生成的可以中斷函數(shù),并用向發(fā)送消息。

PHP編程中的并發(fā)

周末去北京面了兩個(gè)公司,認(rèn)識(shí)了幾位技術(shù)牛人,面試中聊了很多,感覺收獲頗豐。認(rèn)識(shí)到了自己的不足之處,也堅(jiān)定了自己對(duì)計(jì)算機(jī)學(xué)習(xí)的信心。本文是對(duì)其中一道面試題的總結(jié)。

面試中有一個(gè)問題沒有很好的回答出來,題目為:并發(fā)3個(gè)http請(qǐng)求,只要其中一個(gè)請(qǐng)求有結(jié)果,就返回,并中斷其他兩個(gè)。

當(dāng)時(shí)考慮的內(nèi)容有些偏離題目原意, 一直在考慮如何中斷http請(qǐng)求,大概是在 client->recv() 之前去判斷結(jié)果是否已經(jīng)產(chǎn)生,所以回答的是用 socket 去發(fā)送一個(gè) http 請(qǐng)求,把 socket 加入 libevent 循環(huán)監(jiān)聽,在callback中判斷是否已經(jīng)得到結(jié)果,如果已經(jīng)得到結(jié)果,就直接 return。

后來自己越說越覺得不對(duì),既然已經(jīng)recv到結(jié)果,就不能算是中斷http請(qǐng)求。何況自己從來沒用過libevent。后來說了還說了兩種實(shí)現(xiàn),一個(gè)是用 curl_multi_init, 另一個(gè)是用golang實(shí)現(xiàn)并發(fā)。
golang的版本當(dāng)時(shí)忘了close的用法,結(jié)果并不太符合題意。

這題沒答上來,考官也沒為難我。但是心里一直在考慮,直到面試完走到樓下有點(diǎn)明白什么意思了,可能考的是并發(fā),進(jìn)程線程的應(yīng)用。所以總結(jié)了這篇文章,來講講PHP中的并發(fā)。
本文大約總結(jié)了PHP編程中的五種并發(fā)方式,最后的Golang的實(shí)現(xiàn)純屬無聊,可以無視。如果有空,會(huì)再補(bǔ)充一個(gè)libevent的版本。

curl_multi_init

文檔中說的是 Allows the processing of multiple cURL handles asynchronously. 確實(shí)是異步。這里需要理解的是select這個(gè)方法,文檔中是這么解釋的Blocks until there is activity on any of the curl_multi connections.。了解一下常見的異步模型就應(yīng)該能理解,select, epoll,都很有名,這里引用一篇非常好的文章,有興趣看下解釋吧。

 0);

//close the handles
curl_multi_remove_handle($mh, $ch_1);
curl_multi_remove_handle($mh, $ch_2);
curl_multi_close($mh);

這里我設(shè)置的是,select得到結(jié)果,就退出循環(huán),并且刪除 curl resource, 從而達(dá)到取消http請(qǐng)求的目的。

swoole_client

swoole_client提供了異步模式,我竟然把這個(gè)忘了。這里的sleep方法需要swoole版本大于等于1.7.21, 我還沒升到這個(gè)版本,所以直接exit也可以。

on("connect", function($cli) {
    $req = "GET / HTTP/1.1

    Host: www.baidu.com

    Connection: keep-alive

    Cache-Control: no-cache

    Pragma: no-cache

";

    for ($i=0; $i < 3; $i++) {
        $cli->send($req);
    }
});
$client->on("receive", function($cli, $data){
    echo "Received: ".$data."
";
    exit(0);
    $cli->sleep(); // swoole >= 1.7.21
});
$client->on("error", function($cli){
    echo "Connect failed
";
});
$client->on("close", function($cli){
    echo "Connection close
";
});
//發(fā)起網(wǎng)絡(luò)連接
$client->connect("183.207.95.145", 80, 1);
process

哎,竟然忘了 swoole_process, 這里就不用 pcntl 模塊了。但是寫完發(fā)現(xiàn),這其實(shí)也不算是中斷請(qǐng)求,而是哪個(gè)先到讀哪個(gè),忽視后面的返回值。

useQueue();
    $pid = $process->start();
    $workers[$pid] = $process;
}

foreach($workers as $pid => $process){
    //子進(jìn)程也會(huì)包含此事件
    swoole_event_add($process->pipe, function ($pipe) use($process, $lock, &$finished) {
        $lock->lock();
        if(!$finished){
            $finished = true;
            $data = $process->read();
            echo "RECV: " . $data.PHP_EOL;
        }
        $lock->unlock();
    });
}

function process(swoole_process $process){
    $response = "http response";
    $process->write($response);
    echo $process->pid,"	",$process->callback .PHP_EOL;
}

for($i = 0; $i < $worker_num; $i++) {
    $ret = swoole_process::wait();
    $pid = $ret["pid"];
    echo "Worker Exit, PID=".$pid.PHP_EOL;
}
pthreads

編譯pthreads模塊時(shí),提示php編譯時(shí)必須打開ZTS, 所以貌似必須 thread safe 版本才能使用. wamp中多php正好是TS的,直接下了個(gè)dll, 文檔中的說明復(fù)制到對(duì)應(yīng)目錄,就在win下測試了。 還沒完全理解,查到文章說 php 的 pthreads 和 POSIX pthreads是完全不一樣的。代碼有些爛,還需要多看看文檔,體會(huì)一下。

url = "http://www.baidu.com";
    }
    public function run(){}
}

class Process extends Worker {
    private $text = "";
    public function __construct($text,$object){
        $this->text = $text;
        $this->object = $object;
    }
    public function run(){
        while (is_null($this->object->response)){
            print " Thread {$this->text} is running
";
            $this->object->response = "http response";
            sleep(1);
        }
    }
}

$foo = new Foo();

$a = new Process("A",$foo);
$a->start();

$b = new Process("B",$foo);
$b->start();

echo $foo->response;
yield

yield生成的generator,可以中斷函數(shù),并用send向 generator 發(fā)送消息。
稍后補(bǔ)充協(xié)程的版本。還在學(xué)習(xí)中。

Golang

用Go實(shí)現(xiàn)比較簡單, 回家后查了查 close,處理一下 panic就ok了。代碼如下:

package main

import (
    "fmt"
)

func main() {
    var result chan string = make(chan string, 1)
    for index := 0;  index< 3; index++ {
        go doRequest(result)
    }

    res, ok := <-result
    if ok {
        fmt.Println("received ", res)
    }

}

func doRequest(result chan string)  {
    response := "http response"
    defer func() {
        if x := recover(); x != nil {
            fmt.Println("Unable to send: %v", x)
        }
    }()
    result <- response
    close(result)
}

上面的幾個(gè)方法,除了 curl_multi_* 貌似符合題意外(不確定,要看下源碼),其他的方法都沒有中斷請(qǐng)求后recv()的操作, 如果得到response后還有后續(xù)操作,那么是有用的,否則并沒有什么意義。想想可能是PHP操作粒度太大, 猜測用 C/C++ 應(yīng)該能解決問題。

寫的時(shí)候沒有注意到一個(gè)問題,有些方式是返回值,有些直接打印了,這樣不好,應(yīng)該統(tǒng)一使用返回值得到請(qǐng)求結(jié)果。能力有限,先這樣吧。

最后要做個(gè)廣告,計(jì)蒜客是一家致力于計(jì)算機(jī)科學(xué)高端教育的公司,如果你對(duì)編程或者計(jì)算機(jī)底層有興趣,不妨去他們網(wǎng)站學(xué)習(xí)學(xué)習(xí)。
同時(shí),公司也一直在招人,如果你對(duì)自己的能力有信心,可以去試試。公司非常自由開放,90后為主。牛人也有不少,ACM世界冠軍,知乎大牛。
公司主做教育,內(nèi)部學(xué)習(xí)資料必須給力,我只看到了一些關(guān)于操作系統(tǒng)的測試題,涉及到的知識(shí)面很廣,可見公司平均技術(shù)能力有多厲害。

如果文章中有疏漏,錯(cuò)誤,還請(qǐng)大神們不吝指出,幫助菜鳥進(jìn)步,謝謝。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/21254.html

相關(guān)文章

  • PHP并發(fā)IO編程之路

    摘要:下文如無特殊聲明將使用進(jìn)程同時(shí)表示進(jìn)程線程。收到數(shù)據(jù)后服務(wù)器程序進(jìn)行處理然后使用向客戶端發(fā)送響應(yīng)?,F(xiàn)在各種高并發(fā)異步的服務(wù)器程序都是基于實(shí)現(xiàn)的,比如。 并發(fā) IO 問題一直是服務(wù)器端編程中的技術(shù)難題,從最早的同步阻塞直接 Fork 進(jìn)程,到 Worker 進(jìn)程池/線程池,到現(xiàn)在的異步IO、協(xié)程。PHP 程序員因?yàn)橛袕?qiáng)大的 LAMP 框架,對(duì)這類底層方面的知識(shí)知之甚少,本文目的就是詳細(xì)介...

    Riddler 評(píng)論0 收藏0
  • PHP 協(xié)程:Go + Chan + Defer

    摘要:為語言提供了強(qiáng)大的協(xié)程編程模式。提供的協(xié)程語法借鑒自,在此向開發(fā)組致敬協(xié)程可以與很好地互補(bǔ)。并發(fā)執(zhí)行使用創(chuàng)建協(xié)程,可以讓和兩個(gè)函數(shù)變成并發(fā)執(zhí)行。協(xié)程需要拿到請(qǐng)求的結(jié)果。 Swoole4為PHP語言提供了強(qiáng)大的CSP協(xié)程編程模式。底層提供了3個(gè)關(guān)鍵詞,可以方便地實(shí)現(xiàn)各類功能。 Swoole4提供的PHP協(xié)程語法借鑒自Golang,在此向GO開發(fā)組致敬 PHP+Swoole協(xié)程可以與...

    nidaye 評(píng)論0 收藏0
  • 聊聊 2018 年后端技術(shù)趨勢(shì)

    摘要:現(xiàn)在在后端業(yè)務(wù)開發(fā)編程方面,技術(shù)力量強(qiáng)的團(tuán)隊(duì)已經(jīng)開始將技術(shù)棧從同步模式切換為異步了。使用這些技術(shù)方案是無法兼容已有程序的。影響了異步回調(diào)技術(shù)棧的普及。將會(huì)成為未來后端開發(fā)領(lǐng)域的主流技術(shù)方案。 今天太忙,少寫一點(diǎn),后面再補(bǔ)充。 異步模式 Go 語言越來越熱門,很多大型互聯(lián)網(wǎng)公司后端正在轉(zhuǎn)向 GO 。Java 圈知名的服務(wù)化框架 Dubbo 也宣布轉(zhuǎn)型異步模式。這是一個(gè)大趨勢(shì),異步模式已經(jīng)...

    Miyang 評(píng)論0 收藏0
  • PHP回顧之協(xié)程

    摘要:本文先回顧生成器,然后過渡到協(xié)程編程。其作用主要體現(xiàn)在三個(gè)方面數(shù)據(jù)生成生產(chǎn)者,通過返回?cái)?shù)據(jù)數(shù)據(jù)消費(fèi)消費(fèi)者,消費(fèi)傳來的數(shù)據(jù)實(shí)現(xiàn)協(xié)程。解決回調(diào)地獄的方式主要有兩種和協(xié)程。重點(diǎn)應(yīng)當(dāng)關(guān)注控制權(quán)轉(zhuǎn)讓的時(shí)機(jī),以及協(xié)程的運(yùn)作方式。 轉(zhuǎn)載請(qǐng)注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎(chǔ) web請(qǐng)求 cookie web響應(yīng) sess...

    Java3y 評(píng)論0 收藏0
  • php異步編程

    摘要:配合或者自身的已經(jīng)可以滿足很多請(qǐng)求異步化的需求。協(xié)程與異步既然協(xié)程可以被中斷,那么只要在程序發(fā)起請(qǐng)求后發(fā)起事件循環(huán),然后用返回,然后程序繼續(xù)執(zhí)行主程序部分,等事件返回后觸發(fā)函數(shù),執(zhí)行或來繼續(xù)執(zhí)行協(xié)程部分。 前言 我對(duì) php 異步的知識(shí)還比較混亂,寫這篇是為了整理,可能有錯(cuò)。 傳統(tǒng)的 php-fpm 一個(gè)進(jìn)程執(zhí)行一個(gè)請(qǐng)求,要達(dá)到多少并發(fā),就要生成多少個(gè)進(jìn)程。更糟糕的是每次請(qǐng)求都需要重新...

    antyiwei 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

lewinlee

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<