Как изящно разбудить или прекратить спящий поток std :: thread?

#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 ++?

1

Решение

Я бы рекомендовал спать на широковещательном сигнале, семафоре, условной переменной или чем-то другом вместо того, чтобы выполнять блокирующий сон. Тогда ваше приложение просто устанавливает сигнал, и любой, кто спать проснется и может выйти. Это гораздо более чистое решение, так как оно дает телу нити возможность очистить все, что он может делать, включая снятие блокировок!

Ответ на обновление
В этом конкретном случае звоните select с таймаутом перед звонком accept,

8

Другие решения

Первая проблема возникает из режима блокировки сокета принять, вы должны использовать неблокирующий режим сокета.

Вы можете установить флаг в цикле 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) в примере, вы можете использовать условную переменную (предпочтительный способ).

4

По вопросам рекламы [email protected]