我安裝了 swoole 擴(kuò)展和 revolt/event-loop 來測(cè)試協(xié)程的效果
process.php 里依次對(duì)三種情況進(jìn)行測(cè)試:
'webman' => [
'handler' => Http::class,
'listen' => 'http://0.0.0.0:8787',
'count' => 1,
'user' => '',
'group' => '',
'reusePort' => false,
// 'eventLoop' => "",
'eventLoop' => \Workerman\Events\Swoole::class,
// 'eventLoop' => \Workerman\Events\Fiber::class,
'context' => [],
'constructor' => [
'requestClass' => Request::class,
'logger' => Log::channel('default'),
'appPath' => app_path(),
'publicPath' => public_path()
]
],
控制器代碼如下:
public function json(Request $request)
{
Timer::sleep(10);
// usleep(1000*30);
return json(['code' => 0, 'msg' => "ok",'data'=>$request->cookie()]);
}
依次快速發(fā)出兩個(gè)請(qǐng)求,發(fā)現(xiàn)第2 個(gè)請(qǐng)求是在第一個(gè)請(qǐng)求結(jié)束后才開始處理的,第一個(gè)請(qǐng)求耗時(shí) 10.x 秒,第二個(gè)請(qǐng)求耗時(shí) 20 秒。
用協(xié)程不是應(yīng)該兩個(gè)請(qǐng)求同時(shí)被處理嗎,怎么三種eventLoop
配置的效果都一樣?
是不是協(xié)程并非框架自動(dòng),必須要手動(dòng)創(chuàng)建協(xié)程并投遞任務(wù):
Coroutine::create(function () use ($request) {
Timer::sleep(10);
var_dump(sprintf("%s-%d","你好協(xié)程",time()));
});
但如果是手動(dòng)的話,為什么文檔里又要求下面這樣,按理來說控制器方法內(nèi)部就不是協(xié)程,就不需要使用 Context?
class TestController
{
public function index(Request $request)
{
Context::set('name', $request->get('name'));
Timer::sleep(5);
return Context::get('name');
}
}
是我理解哪里出了問題嗎
是指在協(xié)程狀態(tài)下 全局變量污染 所以 才需要 Context::set Context::get
文檔里的第一個(gè)例子寫的很清楚 自己測(cè)下就曉得了
將進(jìn)程數(shù)設(shè)置為1,當(dāng)我們連續(xù)發(fā)起兩個(gè)請(qǐng)求時(shí)
http://127.0.0.1:8787/test?name=lilei
http://127.0.0.1:8787/test?name=hanmeimei
我們期望兩個(gè)請(qǐng)求返回的結(jié)果分別是 lilei 和 hanmeimei,但實(shí)際上返回的都是hanmeimei。
這是因?yàn)榈诙€(gè)請(qǐng)求將靜態(tài)變量$name覆蓋了,第一個(gè)請(qǐng)求睡眠結(jié)束時(shí)返回時(shí)靜態(tài)變量$name已經(jīng)成為hanmeimei