c-在文件服务器中休眠工作线程



我正在实现一个文件服务器,它接收来自多个客户端的请求。每个客户端发送多个请求。在服务器端,主线程生成一个新的工作线程,以便在每次连接新客户端时处理请求。一个工作线程处理来自为其创建的客户端的所有请求。因此,在线程处理一个请求后,当来自同一客户端的另一个请求到达时,它等待被主线程唤醒。

我不知道如何实现最后一行。这就是我如何让线程休眠并再次唤醒它。

感谢

使用条件变量https://computing.llnl.gov/tutorials/pthreads/#ConVarSignal

您不会"让线程进入睡眠状态"。线程在进行任何阻塞系统调用时都会休眠。

有很多方法可以实现您所描述的内容,最常见的可能是"线程池模式"。这通常使用线程安全队列来实现,而线程安全队列又可以使用互斥和条件变量来实现。

当工作线程等待条件变量(pthread_cond_wait)时,它将进入睡眠状态,而主线程将通过用信号通知条件变量(pt hread_cond-signal)来唤醒它。

稍微搜索一下,就会发现许多基于pthread的队列示例代码。

您的客户端处理线程是否保持客户端的任何状态?如果是这样的话,我可以理解为什么每个客户端都需要一个专用线程。如果是这种情况,您可以按照Cnicutar和其他海报的建议,为每个客户端处理程序线程使用生产者-消费者队列。我通常使用信号量与互斥体进行同步,因为这种同步在所有平台上都可用,但condvars还可以。当文件请求传入时,不清楚如何识别客户端,因此管理客户端线程可能会很尴尬,也可能不会。当一个文件请求进入主线程时,你怎么知道该把它推到哪个队列上?

Rgds,Martin

你应该研究生产者-消费者的问题。简而言之,你想做这样的事情:

  • 工作线程尝试从队列中获取"作业"
  • 如果队列为空,线程将阻塞(信号量/条件变量),否则它将获取作业并对其进行处理
  • 主队列作业放入队列中,并通知工人("嘿,还有工作要做")
  • 收到通知的工作人员立即醒来,并尝试从队列中获取作业

诀窍是做到真正优雅:

  • get应自动队列为空时阻止
  • 放置应自动信号工人正在等待

您将如何使用Linux所提供的内容来做到这一点?

  • sempahores
  • pthreads条件变量

现在,回到你的问题上来。为每个客户端启动一个线程似乎有点可疑。如果您可以有一个线程池来处理来自任何客户端的请求,那么方式会更简单。

我通过在客户端连接开始时创建的线程解决了这个问题,然后线程直接接收并向客户端发送消息,而不是在工作线程完成任务后由主线程接收和发送消息。

您有几种可能性,但我实现了类似的多线程解决方案,如下所示:

  • 允许工作线程的方法在没有工作要做时返回
  • 当您的父线程收到一个请求时,将其添加到工作线程的队列中,并调用一个"Wakeup"方法,如下所示:

    private void Wakeup()
    {
        if (!_workerThread.IsBusy)
            _workerThread.RunWorkerAsync();
    }
    

这将允许您在睡眠状态下不挂起线程,因为它需要定期检查是否已请求唤醒。这就把唤醒工作线程的责任推到了父线程上。

最新更新