[英]How to stop thread by another thread?
我有2个线程,一个是按时间升序,另一个是输入密码,当第一个线程达到100或在其他线程输入时如何停止两个线程? 请给我一些想法
使用 C++20 协同取消:
#include <thread>
void thread_start(std::stop_token token) {
while (!token.stop_requested()) {
// ...
}
}
void launch_thread() {
std::stop_source stop_source;
std::thread th { thread_start, stop_source.get_token() };
// ...
stop_source.request_stop();
th.join()
}
使用 C++20 std::jthread
更容易
#include <thread>
void thread_start(std::stop_token token) {
while (!token.stop_requested()) {
// ...
}
}
void launch_thread() {
std::jthread th { thread_start };
// ...
// request_stop() implicitly called by std::~jthread
}
正如理查德所说,您将需要条件变量,并且您需要考虑一些竞争条件。 这是一个例子:
#include <condition_variable>
#include <future>
#include <iostream>
#include <mutex>
#include <chrono>
enum class thread_state
{
starting,
started,
stopping,
stopped
};
class thread_state_t
{
public:
thread_state_t() :
m_state{ thread_state::starting }
{
}
void stop()
{
std::unique_lock<std::mutex> lock{ m_mtx };
if (m_state == thread_state::started)
{
m_state = thread_state::stopping;
m_cv.notify_all();
}
}
void set_started()
{
std::unique_lock<std::mutex> lock{ m_mtx };
if (m_state == thread_state::starting)
{
m_state = thread_state::started;
m_cv.notify_all();
}
}
void set_stopped()
{
std::unique_lock<std::mutex> lock{ m_mtx };
m_state = thread_state::stopped;
m_cv.notify_all();
}
void wait_for_state(const thread_state state)
{
std::unique_lock<std::mutex> lock{ m_mtx };
m_cv.wait(lock, [&] {return m_state == state; });
}
bool is_running()
{
std::unique_lock<std::mutex> lock{ m_mtx };
return (m_state == thread_state::started);
}
private:
std::mutex m_mtx;
std::condition_variable m_cv;
thread_state m_state;
};
int main()
{
auto thread1_state = std::make_shared<thread_state_t>();
// important capture thread1_state by value
// so its lifetime gets extended for the duration of this thread
auto f1 = std::async(std::launch::async, [thread1_state]
{
thread1_state->set_started();
std::cout << "thread 1 started\n";
while (thread1_state->is_running())
{
// simulate doing some work.
std::cout << ".";
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
thread1_state->set_stopped();
std::cout << "thread 1 done\n";
});
// important due to thread scheduling we must
// wait for thread1 to be in a started state so we also know it is ready to receive a
// stop signal if we don't do that we can have raceconditions
std::cout << "main thread waiting for thread 1 to start and be in a stable state\n";
thread1_state->wait_for_state(thread_state::started);
// start the second thread
auto f2 = std::async(std::launch::async, [thread1_state]
{
std::cout << "thread 2 started\n";
// simulate some work before stopping thread 1.
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "thread 2 asking thread 1 to stop\n";
thread1_state->stop();
std::cout << "thread 2 waiting for thread 1 to have stopped\n";
thread1_state->wait_for_state(thread_state::stopped);
std::cout << "thread 2 done\n";
});
// synchronize with both threads
f2.get();
f1.get();
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.