1
#include <thread>
#include <chrono>

using namespace std:

void f()
{
    // Sleeping for a very long while
    while (SOCKET s = accept(listening_socket, ...))
    {
         // ...
    }

}

int main()
{
    std::thread t(f);
    DoSomething();
    t.???(); /* What to place here to wake/terminate thread f? */
}

在Win32下,我可以用TerminateThread()杀死一个线程。但我想要的是一种跨平台的方法来做到这一点。

我应该如何在 C++ 中优雅地做到这一点?

4

2 回答 2

8

我建议在广播信号、信号量、条件变量或其他东西上睡觉,而不是阻塞睡眠。然后您的应用程序只需设置信号,任何正在睡觉的人都会醒来并可以退出。这是一个更清洁的解决方案,因为它让线程体有机会清理它可能正在做的任何事情——包括释放锁!

对更新的响应
在这种特定情况下,在调用select之前调用超时accept

于 2013-02-15T01:38:48.070 回答
4

第一个问题来自阻塞模式套接字接受,你应该使用非阻塞套接字模式。

您可以在 while 循环中设置标志,例如:

struct AcceptHandler
{
  AcceptHandler()
  : is_terminated(false)
  {
  }

  void accept()
  {
    while(!is_terminated)
    {
       // select
       // accept
      cout << " in loop " << endl;
    }
  }

  void terminate()
  {
    is_terminated = true;
  }

private:
  std::atomic<bool> is_terminated;
};

int main()
{
  AcceptHandler ah;
  std::thread t(std::bind(&AcceptHandler::accept, std::ref(ah)));
  t.join(); /// this is just demo, it blocks here

  ah.terminate();

  return 0;
}

我在示例中使用了一个标志(is_terminated),您可以使用条件变量(首选方式)。

于 2013-02-15T02:02:33.603 回答