我在下面看到An example on how to use libuv with libcurl
的示例代码主要功能如下所示:
int main(int argc, char **argv) {
loop = uv_default_loop();
if (argc <= 1)
return 0;
if (curl_global_init(CURL_GLOBAL_ALL)) {
fprintf(stderr, "Could not init cURL\n");
return 1;
}
uv_timer_init(loop, &timeout);
curl_handle = curl_multi_init();
curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket);
curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);
while (argc-- > 1) {
add_download(argv[argc], argc);
}
uv_run(loop, UV_RUN_DEFAULT);
curl_multi_cleanup(curl_handle);
return 0;
}
我很困惑如何让事件循环开始。因为它看起来像我们执行这一行
uv_run(loop, UV_RUN_DEFAULT);
循环中根本没有待处理的事件,所以理论上不应该立即退出循环?
回调handle_socket应该没有运行的更改。 curl_perform()
没有机会在curl套接字回调的回调中设置运行。
我的理解有什么问题吗?
答案 0 :(得分:0)
来自uv_run
的文档:
/*
* This function runs the event loop. It will act differently depending on the
* specified mode:
* - UV_RUN_DEFAULT: Runs the event loop until the reference count drops to
* zero. Always returns zero.
* - UV_RUN_ONCE: Poll for new events once. Note that this function blocks if
* there are no pending events. Returns zero when done (no active handles
* or requests left), or non-zero if more events are expected (meaning you
* should run the event loop again sometime in the future).
* - UV_RUN_NOWAIT: Poll for new events once but don't block if there are no
* pending events. Returns zero when done (no active handles
* or requests left), or non-zero if more events are expected (meaning you
* should run the event loop again sometime in the future).
*/
在您的情况下,您使用uv_run
致电UV_RUN_DEFAULT
,并且您的引用计数永远不会为零。这意味着循环将实际阻塞,直到您销毁其所有句柄和引用。但是,如果您使用UV_RUN_NOWAIT
运行循环,函数将立即返回。
答案 1 :(得分:0)
uv_timer_init(loop, &timeout)
未挂起套接字,因此它不会阻止uv循环,因为它不活动(您可以检查uv_handle_active)
但curl_multi_add_handle
调用超时回调函数(start_timeout
),此函数启动timeout
计时器,uv_run调用on_timeout
回调。
您可以在curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);
循环后移动add_download
进行测试,然后停止工作。
答案 2 :(得分:-1)
注册异步观察程序。使用uv_async_init
永久强制循环。然后在异步回调中发布并处理所有新请求。