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 に答える