libuv 高并发异步使用

问题来源:
在开发libuv客户端-服务器时,需要并发的向客户端发送数据,libuv就会用到 uv_write函数,因此,我的初步方案是:
1. 创建线程池;
2. 线程池分配数据内存buf,并打包;
3. 将包发给 uv_write;
4. uv_write_cb 中释放buf;
通过开辟30个线程,发现客户端能正确接收数据,但是无法调用uv_write_cb ,导致内存增加,通过查官方文档:
The async thread communication works on loops so although any thread can be the message sender, only threads with libuv loops can be receivers (or rather the loop is the receiver). libuv will invoke the callback (print_progress) with the async watcher whenever it receives a message.
大概的意思是,只有经过loop的ibuv内部的函数才能调用回调函数,可以采用的方案是,将数据发送在uv_queue_work中调用,经过测试,uv_write_cb可以正确响应。
线程池采用的方案是:
1.创建自己线程池 self_pool;
2. 组数据包buf1, 并将buf1发送给uv_queue_work;
3. uv_queue_work 的uv_work函数解析buf1并将数据发送给uv_write;
经过测试 发现如果self_pool有1个以上线程, 函数会崩溃,就是说并发处理uv_queue_work,导致程序问题,加锁也无效。
改进方案:
1.创建自己线程池 self_pool;
2. 创建单线程thread;
3. self_pool组数据包buf1 并将数据加入queue中
4. thread获取buf,创建req对象并将数据发送给uv_queue_work
5.uv_queue_work 的uv_work函数解析buf1并将数据发送给uv_write;
经过测试,以上方案没有问题
继续查阅文档,发现uv_async_send也可以作为其它外界线程调用接口,但是uv_async_t.data并不是线程安全的,同时uv_async_t如果并发处理,在uv_async_send的回调函数没有响应前,多路调用可能会并入一路,也就是说N个调用可能会只有一个回调函数响应。
处理方案1
1. 创建uv_async_t对象async,并加入set中;
2. uv_async_init并调用uv_async_send;
3. 在回调函数中 uv_close((uv_handle_t*) &async, NULL);如果不作处理,将会一直阻塞
4. 从set删除记录。
方案2
1.创建两个队列queue1作为空闲队列, queue2作为忙队列;
2.创建N个uv_async_t放入queue1中;
3.当需要发送数据时,从queue 中取空闲uv_async_t异步发送
4.在回调函数中,将uv_async_t放入queue2中

参考:
libuv的多线程之间传递消息 :https://www.cnblogs.com/guoxiaoqian/p/3945242.html
libuv之async使用
https://blog.csdn.net/limite_god/article/details/43700325
基于libuv的TCP设计
http://www.cnblogs.com/wqvbjhc/p/3758141.html

猜你喜欢

转载自blog.csdn.net/xcw_1987/article/details/79977726