{"action":"created","issue":{"url":"https://api.github.com/repos/swoole/swoole-src/issues/237","labels_url":"https://api.github.com/repos/swoole/swoole-src/issues/237/labels{/name}","comments_url":"https://api.github.com/repos/swoole/swoole-src/issues/237/comments","events_url":"https://api.github.com/repos/swoole/swoole-src/issues/237/events","html_url":"https://github.com/swoole/swoole-src/issues/237","id":69078468,"number":237,"title":"在swoole的task里 使用curl_multi_select 会比较慢","user":{"login":"ronalfei","id":792840,"avatar_url":"https://avatars.githubusercontent.com/u/792840?v=3","gravatar_id":"","url":"https://api.github.com/users/ronalfei","html_url":"https://github.com/ronalfei","followers_url":"https://api.github.com/users/ronalfei/followers","following_url":"https://api.github.com/users/ronalfei/following{/other_user}","gists_url":"https://api.github.com/users/ronalfei/gists{/gist_id}","starred_url":"https://api.github.com/users/ronalfei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ronalfei/subscriptions","organizations_url":"https://api.github.com/users/ronalfei/orgs","repos_url":"https://api.github.com/users/ronalfei/repos","events_url":"https://api.github.com/users/ronalfei/events{/privacy}","received_events_url":"https://api.github.com/users/ronalfei/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-04-17T06:48:26Z","updated_at":"2015-04-17T16:26:50Z","closed_at":null,"body":"在swoole的task里 使用curl_multi_select 会比较慢, 不知道是否是个problem?"},"comment":{"url":"https://api.github.com/repos/swoole/swoole-src/issues/comments/94021239","html_url":"https://github.com/swoole/swoole-src/issues/237#issuecomment-94021239","issue_url":"https://api.github.com/repos/swoole/swoole-src/issues/237","id":94021239,"user":{"login":"andot","id":232161,"avatar_url":"https://avatars.githubusercontent.com/u/232161?v=3","gravatar_id":"","url":"https://api.github.com/users/andot","html_url":"https://github.com/andot","followers_url":"https://api.github.com/users/andot/followers","following_url":"https://api.github.com/users/andot/following{/other_user}","gists_url":"https://api.github.com/users/andot/gists{/gist_id}","starred_url":"https://api.github.com/users/andot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andot/subscriptions","organizations_url":"https://api.github.com/users/andot/orgs","repos_url":"https://api.github.com/users/andot/repos","events_url":"https://api.github.com/users/andot/events{/privacy}","received_events_url":"https://api.github.com/users/andot/received_events","type":"User","site_admin":false},"created_at":"2015-04-17T16:26:50Z","updated_at":"2015-04-17T16:26:50Z","body":"用 curl 的 multi 功能时，可以不用 curl_multi_select，比如在 hprose-php 中，是这样使用 multi 功能来完成并发调用的：\r\n\r\n```\r\n        protected function asyncSendAndReceive($request, $use) {\r\n            $curl = curl_init();\r\n            $this->initCurl($curl, $request);\r\n            curl_multi_add_handle($this->multicurl, $curl);\r\n            $this->curls[] = $curl;\r\n            $this->uses[] = $use;\r\n        }\r\n        public function loop() {\r\n            $count = count($this->curls);\r\n            if ($count === 0) return;\r\n            $err = null;\r\n            try {\r\n                $active = null;\r\n                if ($this->curl_version_lt_720) {\r\n                    do {\r\n                        $status = curl_multi_exec($this->multicurl, $active);\r\n                    } while ($status === CURLM_CALL_MULTI_PERFORM);\r\n                }\r\n                else {\r\n                    $status = curl_multi_exec($this->multicurl, $active);\r\n                }\r\n                while ($status === CURLM_OK && $count > 0) {\r\n                    if ($this->curl_version_lt_720) {\r\n                        do {\r\n                            $status = curl_multi_exec($this->multicurl, $active);\r\n                        } while ($status === CURLM_CALL_MULTI_PERFORM);\r\n                    }\r\n                    else {\r\n                        $status = curl_multi_exec($this->multicurl, $active);\r\n                    }\r\n                    $msgs_in_queue = null;\r\n                    while ($info = curl_multi_info_read($this->multicurl, $msgs_in_queue)) {\r\n                        $h = $info['handle'];\r\n                        $index = array_search($h, $this->curls, true);\r\n                        $use = $this->uses[$index];\r\n                        if ($info['result'] === CURLM_OK) {\r\n                            $data = curl_multi_getcontent($h);\r\n                            try {\r\n                                $response = $this->getContents($data);\r\n                                $error = null;\r\n                            }\r\n                            catch (Exception $e) {\r\n                                $response = \"\";\r\n                                $error = $e;\r\n                            }\r\n                            $this->sendAndReceiveCallback($response, $error, $use);\r\n                        }\r\n                        else {\r\n                            $this->sendAndReceiveCallback('', new \\Exception($info['result'] . \": \" . curl_error($h)), $use);\r\n                        }\r\n                        --$count;\r\n                        if ($msgs_in_queue === 0) break;\r\n                    }\r\n                }\r\n            }\r\n            catch (\\Exception $e) {\r\n                $err = $e;\r\n            }\r\n            foreach($this->curls as $i => $curl) {\r\n                curl_multi_remove_handle($this->multicurl, $curl);\r\n                curl_close($curl);\r\n            }\r\n            $this->curls = array();\r\n            $this->uses = array();\r\n            if ($err !== null) {\r\n                throw $err;\r\n            }\r\n        }\r\n```\r\n\r\n简单的说就是在 curl_multi_exec 之后使用 curl_multi_info_read 来获取连接信息，之后直接用 curl_multi_getcontent 来获取结果就行了。这样就不需要使用 curl_multi_select 来阻塞等待了。\r\n\r\n当然，你也可以直接使用 hprose 来完成这个工作，代码量可以从几百行降到几行。"}}