实现select()+ threadpool的正确方法是什么?

时间:2016-12-19 09:24:31

标签: c select

Server:

socket()
bind()
listen()
for(;;) {
    select()
    if it is listenfd {
        accept()
        add to fd_set
    } else {
        add task to thread_pool work queue
        threadpool_add(thread_routine)
    }
}

thread_routine() {
    get connection fd
    read()
    write()
    close(connection fd)
}

此设计存在问题,而select等待来自socket_fd的数据,另一个帖子可能close(socket_fd),这会导致select返回并read(socket_fd)返回EBADF。什么是正确的设计?

2 个答案:

答案 0 :(得分:1)

基本没问题。错误是在套接字上调用thread_routine close。在另一个线程正在或可能正在使用它时,销毁资源永远都不可能。如果这是TCP,更好的选择是在套接字上调用shutdown

答案 1 :(得分:0)

也许这是设计应用程序的更好方法:

  • 一个listen-thread接受连接(即只有select s listen fd)

  • 对于每个接受的连接,立即创建一个新线程或将fd交给现有的空闲线程

  • 在自己的线程中选择客户端fds以进行输入(不在侦听器线程中)

这是一种更直观的设计,可以消除您的问题。您甚至可以在客户端线程中使用阻塞IO(不带select),具体取决于所使用的协议。