|
|
1
3
你有 三 进程的级别,一个父级、一个子级和许多孙子级。去掉这些级别,不要分叉 完全 ;而是在单个流程中使用事件驱动模型。 在粗略的伪代码中(翻译为您的首选语言): listening_fd = create_socket();
EventQueueOfSomeKind q; // kqueue()-style
q.add_or_update_event(listening_fd, EVFILT_READ, EV_ENABLE);
q.add_or_update_event(3, EVFILT_TIMER, EV_ENABLE, NOTE_SECONDS);
FDToContextMapOfSomeKind context_map;
EventVector event_vector; // vector of kevent-like things
while (1) {
q.wait_for_events(&event_vector); // kevent()-style
foreach e <- event_vector {
switch (e.type) {
case EVFILT_READ:
if (listening_fd == e.fd) {
client_sock = accept_connection(e.fd, SOCK_NONBLOCK);
q.add_or_update_event(client_sock, EVFILT_READ, EV_ENABLE);
q.add_or_update_event(client_sock, EVFILT_WRITE, EV_DISABLE);
context_map.add_new_context(client_socket);
} else {
// Must be one of the client sockets
if (e.flags & EV_EOF) {
context_map.remove_context(e.fd);
q.remove_event(e.fd, EVFILT_READ);
q.remove_event(e.fd, EVFILT_WRITE);
close(e.fd);
} else {
recv(e.fd, buffer);
handle_client_input(&context_map[e.fd], buffer);
}
}
break;
case EVFILT_WRITE:
if (has_queued_output(context_map[e.fd])) {
send(e.fd, pull_queued_output(&context_map[e.fd]));
} else {
q.add_or_update_event(client_sock, EVFILT_WRITE, EV_DISABLE);
}
break;
case EVFILT_TIMER:
foreach client_sock,context <- context_map {
push_queued_output(&context, computed_data(context));
q.add_or_update_event(client_sock, EVFILT_WRITE, EV_ENABLE);
}
break;
}
}
}
我掩盖了部分
进一步阅读
|
|
2
0
这是一个使用Linux的解决方案
这个节目很有帮助 https://github.com/eklitzke/epollet/blob/master/poll.c 我在epoll集合中添加了timerfd,因此服务器 持续侦听和接收数据 同时可以 定期向客户端发送数据 。 |
|
|
CalculusLover · 在本例中,fork()是如何工作的? 4 年前 |
|
|
jjmerelo · 使用Proc::Async从绑定管道读取 8 年前 |
|
|
jatinBatra · 编译后生成的二进制文件会发生什么情况[关闭] 8 年前 |
|
|
Jacobo · 从Java调用具有输入和输出重定向的C可执行文件 8 年前 |
|
|
Ran · 每当我尝试执行命令行提示符时,Unity就会阻塞 8 年前 |
|
|
Hatshepsut · 使用命令行参数使用region调用子流程 8 年前 |