vu_async_t是我们要用的handle,这个handle用来在线程间通信的。handl->data可以存放数据。 配合uv_async_send,可以唤醒持有async的消息队列,并调用async的回调,而且这个是跨线程的,只保证uv_async_send调用一次之后,callback也必然至少调用一次, 但是因为是很多线程可以同时发送唤醒消息,所以,也可能被多次调用。
下载文件实时将下载进度发给主线程
/*************************************************************************
> File Name: demo4.c
> Author: ryan_naiquan
> Mail: ryan_naiquan@163.com
> Created Time: Tue 02 Jul 2019 10:53:48 AM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <uv.h>
uv_loop_t *loop;
uv_async_t async;
double percentage;
void fake_download(uv_work_t *req) {
int size = *((int*) req->data);
int downloaded = 0;
while (downloaded < size) {
percentage = downloaded*100.0/size;
async.data = (void*) &percentage;
uv_async_send(&async);
sleep(1);
downloaded += (200+random())%1000; // can only download max 1000bytes/sec,
// but at least a 200;
}
}
void after(uv_work_t *req, int status) {
fprintf(stderr, "Download complete\n");
uv_close((uv_handle_t*) &async, NULL);
}
void print_progress(uv_async_t *handle) {
double percentage = *((double*) handle->data);
fprintf(stderr, "Downloaded %.2f%%\n", percentage);
}
int main() {
loop = uv_default_loop();
uv_work_t req;
int size = 10240;
req.data = (void*) &size;
uv_async_init(loop, &async, print_progress);
uv_queue_work(loop, &req, fake_download, after);
return uv_run(loop, UV_RUN_DEFAULT);
}
单线程
/*************************************************************************
> File Name: uv_async1.c
> Author: ryan_naiquan
> Mail: ryan_naiquan@163.com
> Created Time: Tue 02 Jul 2019 11:25:06 AM CST
************************************************************************/
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <uv.h>
uv_async_t async;
uv_loop_t* loop;
void close_cb(uv_handle_t* handle);
void async_cb(uv_async_t* handle, int status);
void close_cb(uv_handle_t* handle)
{
printf("close the async handle!\n");
}
void async_cb(uv_async_t* handle, int status)
{
printf("async_cb called!\n");
uv_thread_t id = uv_thread_self();
printf("thread id:%lu.\n", id);
uv_close((uv_handle_t*)&async, close_cb); //如果async没有关闭,消息队列是会阻塞的
}
int main()
{
loop = uv_default_loop();
uv_thread_t id = uv_thread_self();
printf("thread id:%lu.\n", id);
uv_async_init(loop, &async,(void *)async_cb);
uv_async_send(&async);
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
多线程
/*************************************************************************
> File Name: uv_async2.c
> Author: ryan_naiquan
> Mail: ryan_naiquan@163.com
> Created Time: Tue 02 Jul 2019 04:37:06 PM CST
************************************************************************/
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <uv.h>
uv_async_t async;
uv_loop_t* loop;
void close_cb(uv_handle_t* handle);
void async_cb(uv_async_t* handle, int status);
void sub_thread(void* arg);
void close_cb(uv_handle_t* handle)
{
printf("close the async handle!\n");
}
void async_cb(uv_async_t* handle, int status)
{
printf("async_cb called!\n");
uv_thread_t id = uv_thread_self();
printf("thread id:%lu.\n", id);
uv_close((uv_handle_t*)&async, close_cb); //如果async没有关闭,消息队列是会阻塞的
}
/**
*
*/
void sub_thread(void* arg)
{
uv_thread_t id = uv_thread_self();
printf("sub thread id:%lu.\n", id);
uv_async_send(&async);
}
int main()
{
loop = uv_default_loop();
uv_thread_t id = uv_thread_self();
printf("thread id:%lu.\n", id);
uv_async_init(loop, &async, (void *)async_cb);
//创建子线程
uv_thread_t thread;
uv_thread_create(&thread, sub_thread, NULL);
uv_run(loop, UV_RUN_DEFAULT);
uv_thread_join(&thread); //等待子线程完成
return 0;
}
本文由 Ryan 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2019/07/02 16:39