序列化任务分配:使用线程还是epoll?

时间:2010-06-01 12:39:19

标签: multithreading networking

现在我处于这样一种情况:多个客户端都有一组预定义的任务(任何客户端都可以执行任何任务)。当客户端连接到服务器时,服务器从未完成的任务中选择一个任务并将其发送到客户端---服务器端的工作非常容易。客户端需要一段时间才能完成任务并将结果发送回服务器。

由于任务只应发送给一个客户端,因此服务器应以序列化方式处理请求。现在我有两个计划:为每个客户端连接创建一个线程,所有线程轮流访问任务池,或者对每个客户端事件使用epoll监听所有连接和进程。

哪一个更适合这份工作?或者还有其他想法吗?服务器将在多核机器上运行。

2 个答案:

答案 0 :(得分:1)

主要问题是服务器是否需要进行大量处理才能为客户端准备任务。如果没有,那么使用多个线程就没有任何好处 - 相反,上下文切换只会增加开销。在这种情况下,最好使用epoll(最有可能通过一些现有的库,具体取决于您使用的编程语言)。

如果在服务器端进行了重要处理,它可能会抵消上下文切换的低效率,并通过从多个核心获得并行性来提高性能。确定最佳解决方案的唯一方法是进行一些原型设计和分析。

客户端是否与服务器在同一台计算机上运行? 如果是,您将能够轻松利用多个核心。

答案 1 :(得分:0)

你可以做到这两点。您可以在同一个fd-set上运行多个线程epoll(),操作系统将根据需要唤醒线程。这样做也很容易 - 特别是如果你不需要任何共享:只需要fork()五十次左右,如果需要,Linux将进行上下文切换,如果不需要,则进行epoll切换。当我这样做时,我只是做这样的事情:

{char*s=getenv("THREADS");int n=atoi(s?s:"0"),i;
 for(i=0;i<n;i++)if(fork()==0)break;}

如果需要共享,那么您将需要锁定。 这个可以使这里的事情复杂化,并且这些编程问题在一般意义上难以解决。根据我的经验,除了一些非常简单的数据库之外,放弃线程或重新设计程序以不需要锁定共享结构通常更简单。