簡體   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