libuv中handle在不同的loop之间transfer
2016-09-28 17:26
302 查看
对于udp,tcp的handle是可以在不同的loop之间transfer,转移时使用函数uv_udp_init_ex和uv_tcp_init_ex初始化,将handle的flags传入进去即可。 eg:主线程负责监听接受连接请求,另一个线程用传递来的handle,监听读写(防止主线程监听事件过多而影响性能,将部分监视器分配到子线程中去)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
uv_loop_t* loop1;
uv_loop_t* loop2;
uv_async_t async;
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = (char*)malloc(suggested_size);
buf->len = suggested_size;
}
void echo_write(uv_write_t *req, int status) {
if (status) {
fprintf(stderr, "Write error %s\n", uv_strerror(status));
}
free(req);
}
void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread < 0) {
if (nread != UV_EOF)
//fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t*)client, NULL);
}
else if (nread > 0) {
uv_write_t *req = (uv_write_t *)malloc(sizeof(uv_write_t));
uv_buf_t wrbuf = uv_buf_init(buf->base, nread);
printf("read buf:%s\n", buf->base);
uv_write(req, client, &wrbuf, 1, echo_write);
}
if (buf->base)
free(buf->base);
}
void on_new_connection(uv_stream_t *server, int status) {
if (status < 0) {
fprintf(stderr, "New connection error %s\n", uv_strerror(status));
return;
}
char cliIp[17] = { 0 };
int cliPort = 0;
uv_tcp_t *client = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
uv_tcp_init(loop1, client);
if (uv_accept(server, (uv_stream_t*)client) == 0) {
async.data = (void*)client;
uv_async_send(&async);
}
else {
uv_close((uv_handle_t*)client, NULL);
}
}
void async_cb(uv_async_t* handle)
{
printf("async_cb called!\n");
uv_tcp_t* client = (uv_tcp_t*)handle->data;
uv_tcp_init_ex(loop2, client, client->flags);
uv_read_start((uv_stream_t*)client, alloc_buffer, echo_read);
}
void threadFunc(void* arg)
{
loop2 = uv_default_loop();
uv_thread_t id = uv_thread_self();
printf("threadFunc id:%lu.\n", (unsigned long)id);
uv_async_init(loop2, &async, async_cb);
uv_run(loop2, UV_RUN_DEFAULT);
}
int main() {
loop1 = uv_default_loop();
uv_thread_t id = uv_thread_self();
printf("thread id:%lu.\n", id);
//创建子线程
uv_thread_t thread;
uv_thread_create(&thread, threadFunc, NULL);
uv_tcp_t server;
struct sockaddr_in addr;
uv_tcp_init(loop1, &server);
uv_ip4_addr("127.0.0.1", 7000, &addr);
uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
int r = uv_listen((uv_stream_t*)&server, 2, on_new_connection);
if (r) {
fprintf(stderr, "Listen error %s\n", uv_strerror(r));
return 1;
}
uv_run(loop1, UV_RUN_DEFAULT);
uv_thread_join(&thread); //等待子线程完成
getchar();
printf("main thread end!\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
uv_loop_t* loop1;
uv_loop_t* loop2;
uv_async_t async;
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = (char*)malloc(suggested_size);
buf->len = suggested_size;
}
void echo_write(uv_write_t *req, int status) {
if (status) {
fprintf(stderr, "Write error %s\n", uv_strerror(status));
}
free(req);
}
void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread < 0) {
if (nread != UV_EOF)
//fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t*)client, NULL);
}
else if (nread > 0) {
uv_write_t *req = (uv_write_t *)malloc(sizeof(uv_write_t));
uv_buf_t wrbuf = uv_buf_init(buf->base, nread);
printf("read buf:%s\n", buf->base);
uv_write(req, client, &wrbuf, 1, echo_write);
}
if (buf->base)
free(buf->base);
}
void on_new_connection(uv_stream_t *server, int status) {
if (status < 0) {
fprintf(stderr, "New connection error %s\n", uv_strerror(status));
return;
}
char cliIp[17] = { 0 };
int cliPort = 0;
uv_tcp_t *client = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
uv_tcp_init(loop1, client);
if (uv_accept(server, (uv_stream_t*)client) == 0) {
async.data = (void*)client;
uv_async_send(&async);
}
else {
uv_close((uv_handle_t*)client, NULL);
}
}
void async_cb(uv_async_t* handle)
{
printf("async_cb called!\n");
uv_tcp_t* client = (uv_tcp_t*)handle->data;
uv_tcp_init_ex(loop2, client, client->flags);
uv_read_start((uv_stream_t*)client, alloc_buffer, echo_read);
}
void threadFunc(void* arg)
{
loop2 = uv_default_loop();
uv_thread_t id = uv_thread_self();
printf("threadFunc id:%lu.\n", (unsigned long)id);
uv_async_init(loop2, &async, async_cb);
uv_run(loop2, UV_RUN_DEFAULT);
}
int main() {
loop1 = uv_default_loop();
uv_thread_t id = uv_thread_self();
printf("thread id:%lu.\n", id);
//创建子线程
uv_thread_t thread;
uv_thread_create(&thread, threadFunc, NULL);
uv_tcp_t server;
struct sockaddr_in addr;
uv_tcp_init(loop1, &server);
uv_ip4_addr("127.0.0.1", 7000, &addr);
uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
int r = uv_listen((uv_stream_t*)&server, 2, on_new_connection);
if (r) {
fprintf(stderr, "Listen error %s\n", uv_strerror(r));
return 1;
}
uv_run(loop1, UV_RUN_DEFAULT);
uv_thread_join(&thread); //等待子线程完成
getchar();
printf("main thread end!\n");
return 0;
}
相关文章推荐
- web自动化测试第8步:不同窗口之间的切换(handle)
- 不同芯片和设备之间,如何稳定的,安全的通信?
- 链接服务器,不同服务器数据库之间的数据操作
- 不同服务器数据库之间的数据操作
- Activity与Service通信(不同进程之间)
- JSP 和 Servlet 有哪些相同点和不同点, 他们之间的联系是什么?
- Java中不同包下类与类之间的访问
- [转]不同版本的SQL Server之间数据导出导入,降级还原等
- .NET在Visual Studio的不同Tab之间切换
- 不同系统之间的文件传输
- android中不同类之间的数据通信之接口回调
- 不同apk之间数据共享
- Ubuntu 14.10 下安装Synergy,不同电脑之间公用一套键盘鼠标
- 不同Activity之间的数据传递
- cocos2dx 加载cocostudio创建的exportjson文件 不同图片之间会有黑线问题解决方法
- JSP和Servlet 有哪些相同点和不同点,他们之间的联系是什么?
- SQL2008-不同数据库之间的触发器
- 使用类似于中介者模式实现不同VC之间的跳转
- 将用户在不同域之间移动!
- 在不同 ViewController 之间传值