![]() |
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()是如何工作的? 3 年前 |
![]() |
jjmerelo · 使用Proc::Async从绑定管道读取 7 年前 |
![]() |
jatinBatra · 编译后生成的二进制文件会发生什么情况[关闭] 7 年前 |
![]() |
Jacobo · 从Java调用具有输入和输出重定向的C可执行文件 7 年前 |
![]() |
Ran · 每当我尝试执行命令行提示符时,Unity就会阻塞 7 年前 |
![]() |
Hatshepsut · 使用命令行参数使用region调用子流程 7 年前 |