国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

并發(fā)

msup / 2566人閱讀

摘要:面試中有一個(gè)問題沒有很好的回答出來,題目為并發(fā)個(gè)請(qǐng)求,只要其中一個(gè)請(qǐng)求有結(jié)果,就返回,并中斷其他兩個(gè)。后來說了還說了兩種實(shí)現(xiàn),一個(gè)是用另一個(gè)是用實(shí)現(xiàn)并發(fā)。所以總結(jié)了這篇文章,來講講中的并發(fā)。生成的可以中斷函數(shù),并用向發(fā)送消息。

面試中有一個(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,都很有名,這里引用一篇非常好的文章,有興趣看下解釋吧。

// build the individual requests as above, but do not execute them
$ch_1 = curl_init("http://www.baidu.com/");
$ch_2 = curl_init("http://www.baidu.com/");
curl_setopt($ch_1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch_2, CURLOPT_RETURNTRANSFER, true);

// build the multi-curl handle, adding both $ch
$mh = curl_multi_init();
curl_multi_add_handle($mh, $ch_1);
curl_multi_add_handle($mh, $ch_2);

// execute all queries simultaneously, and continue when all are complete
$running = null;
do {
curl_multi_exec($mh, $running);
$ch = curl_multi_select($mh);
if($ch !== 0){

   $info = curl_multi_info_read($mh);
   if($info){
       var_dump($info);
       $response_1 = curl_multi_getcontent($info["handle"]);
       echo "$response_1 
";
       break;
   }

}
} while ($running > 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也可以。

$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
//設(shè)置事件回調(diào)函數(shù)
$client->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è),忽視后面的返回值。

$workers = [];
$worker_num = 3;//創(chuàng)建的進(jìn)程數(shù)
$finished = false;
$lock = new swoole_lock(SWOOLE_MUTEX);

for($i=0;$i<$worker_num ; $i++){

$process = new swoole_process("process");
//$process->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ì)一下。

class Foo extends Stackable {

public $url;
public $response = null;
public function __construct(){
    $this->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é)果。能力有限,先這樣吧。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/22786.html

相關(guān)文章

  • 聊聊面試中關(guān)于并發(fā)問題的應(yīng)對(duì)方案

    摘要:這里呢,我直接給出高并發(fā)場景通常都會(huì)考慮的一些解決思路和手段結(jié)尾如何有效的準(zhǔn)備面試中并發(fā)類問題,我已經(jīng)給出我的理解。 showImg(https://segmentfault.com/img/bV7Viy?w=550&h=405); 主題 又到面試季了,從群里,看到許多同學(xué)分享了自己的面試題目,我也抽空在網(wǎng)上搜索了一些許多公司使用的面試題,目前校招和社招的面試題基本都集中在幾個(gè)大方向上...

    xzavier 評(píng)論0 收藏0
  • 并發(fā)編程 - 探索一

    摘要:并發(fā)表示在一段時(shí)間內(nèi)有多個(gè)動(dòng)作存在。并發(fā)帶來的問題在享受并發(fā)編程帶來的高性能高吞吐量的同時(shí),也會(huì)因?yàn)椴l(fā)編程帶來一些意想不到弊端。并發(fā)過程中多線程之間的切換調(diào)度,上下文的保存恢復(fù)等都會(huì)帶來額外的線程切換開銷。 0x01 什么是并發(fā) 要理解并發(fā)首選我們來區(qū)分下并發(fā)和并行的概念。 并發(fā):表示在一段時(shí)間內(nèi)有多個(gè)動(dòng)作存在。 并行:表示在同一時(shí)間點(diǎn)有多個(gè)動(dòng)作同時(shí)存在。 例如:此刻我正在寫博客,但...

    pcChao 評(píng)論0 收藏0
  • Web開發(fā)中,什么級(jí)別才算是高并發(fā)

    摘要:我思考的是什么才算是高并發(fā)你一天幾個(gè)肯定高不了。所以我得出一個(gè)自定義概念如果某個(gè)系統(tǒng)的日在千萬級(jí)別以上,他就可能是一個(gè)高并發(fā)的系統(tǒng)。高并發(fā)的問題,我們具體該關(guān)心什么講真話,高并發(fā)是個(gè)比較抽象的概念。是指秒鐘響應(yīng)的請(qǐng)求數(shù)量。 這并不是一個(gè)回答的問題的文章,而是由此引發(fā)的一個(gè)思考。 大家心里仔細(xì)想想,當(dāng)你們聽到高并發(fā)網(wǎng)站時(shí),心里對(duì)這個(gè)網(wǎng)站是個(gè)什么概念?首先想到的是淘寶嗎?帶著問題,我們一起...

    yanbingyun1990 評(píng)論0 收藏0
  • 并發(fā)同步控制

    摘要:并發(fā)同步控制遇到并發(fā)時(shí),我們避免不了要談并發(fā)控制。它會(huì)阻塞其它的線程執(zhí)行,如果當(dāng)前線程一直持有的監(jiān)控鎖,就會(huì)把其它線程一直阻塞下去。如果此時(shí)線程和線程同時(shí)進(jìn)入方法,用一段語言描述方法的執(zhí)行過程,可能是這樣子。 并發(fā)同步控制 遇到并發(fā)時(shí),我們避免不了要談并發(fā)控制。在Java語言中,我們談并發(fā)時(shí),要談到Object的監(jiān)控鎖。在MySQL的數(shù)據(jù)庫并發(fā)中,我們也要談到mysql的鎖機(jī)制。 這樣...

    graf 評(píng)論0 收藏0
  • 15 行代碼實(shí)現(xiàn)并發(fā)控制(javascript)

    摘要:而爬蟲一般用多線程來控制并發(fā),然而如果是爬蟲,由于其單線程無阻塞性質(zhì)以及事件循環(huán)機(jī)制,一般不用多線程來控制并發(fā)當(dāng)然也可以實(shí)現(xiàn)多線程,此處非重點(diǎn)不再多講,而是更加簡便地直接在代碼層級(jí)上實(shí)現(xiàn)并發(fā)。下面我們用行代碼實(shí)現(xiàn)一個(gè)并發(fā)控制的函數(shù)。 前言 首發(fā)于 github blog 做過爬蟲的都知道,要控制爬蟲的請(qǐng)求并發(fā)量,其實(shí)也就是控制其爬取頻率,以免被封IP,還有的就是以此來控制爬蟲應(yīng)用運(yùn)...

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

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

0條評(píng)論

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