停止当前正在运行的线程c ++

时间:2018-04-01 12:13:04

标签: c++ multithreading c++11

我有一个管理器类,它为成员的执行方法创建了一个线程。

 int Task::Execute()
    {
        try
        {
            setTaskSeqByName();
            for (int i = 0; i < mTaskSequence.size(); i++)
            {
                if(mCurrentStatus == "running")
                    mTaskSequence[i]->Execute();
            }
        }
        catch (std::exception ex)
        {
            return -1;
        }
        return 0;
    }

我希望能够以不同的线程运行它,这样我就可以执行一个更改mCurrentStatus变量的停止,这样循环就会停止,mTaskSequence[i]任务也会停止。

最好的方法是什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

理论上,您无法暂停或停止正在运行的线程。实现对另一个正在运行的线程的精细控制是一个挑战。但是,使用条件变量,您可以模拟如下所示:

#include "conio.h"
#include <iostream>    
#include <thread>
#include <atomic>
#include <chrono>
#include <mutex>
#include <condition_variable>

using namespace std;

class foo_t
{
private:
    atomic<bool>& running_;
    thread worker_;
    mutex lock_;
    condition_variable signal_;
    atomic<bool> pause_;

public:
    foo_t(atomic<bool>& running): running_(running)
    {
        pause_ = false;
        worker_ = thread([&]() { run(); });
    }

    ~foo_t()
    {
        worker_.join();
    }       

};

方法和属性:

void foo_t::run()
        {
            while (running_)
            {
                unique_lock<mutex> lock(lock_);
                signal_.wait(lock, [&]() { return !running_ || !pause_;  });
                if (!running_) return;

                cout << ".  ";
                this_thread::sleep_for(chrono::milliseconds(100));
            }
        }

condition_variable& foo_t::GetSignal()
        {
            return signal_;
        }

void foo_t::SetPause(bool flag)
        {
            pause_ = flag;
        }

主程序

int main()
{    
    atomic<bool> running = true;

    foo_t foo(running);
    char ch;

    cout << "Press r to Run   Press p to Pause or Press to Exit \n ";

    while ( (ch = getch()) != 'p' || ch !='r'  || ch != 'x')
    {
        if (ch == 'p' )
        {
            cout << "paused\n ";
            foo.SetPause(true);
            foo.GetSignal().notify_one();
        }
        else
            if (ch == 'r' )
            {
                cout << "running\n ";
                foo.SetPause(false);
                foo.GetSignal().notify_one();
            }
            else
                if (ch == 'x')
            {
                running = false;
                foo.GetSignal().notify_one();
                break;
            }    
    }
    running = false;
    return 0;
}