繁体   English   中英

如何通过另一个线程停止线程?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM