【问题标题】:Stop a thread when an event occurs事件发生时停止线程
【发布时间】:2018-09-02 06:06:09
【问题描述】:

我希望main 函数在事件发生时停止function_(在本例中为 1 毫秒后)。我遇到的问题是function_ 立即重新锁定互斥锁,而不让main 函数获取它。

#include <thread>
#include <mutex>
#include <iostream>
#include <chrono>

using namespace std;

void function_(volatile bool *ptrStop, mutex *ptrMtx) {
    for (int i = 0; i < 10; i++) {
        ptrMtx->lock();
        if (*ptrStop) {
            ptrMtx->unlock();
            return;
        }
        //doSomething();
        this_thread::sleep_for(chrono::milliseconds(1));
        cout << "Iteration " << i << endl;
        ptrMtx->unlock();
        //this_thread::sleep_for(chrono::milliseconds(1));
    }
    return;
}


int main() {
    volatile bool stop = 0;
    mutex mtx;

    thread functionThread(function_, &stop, &mtx);

    this_thread::sleep_for(chrono::milliseconds(1));
    mtx.lock();
    stop = 1;
    mtx.unlock();
    cout << "Changed boolean variable value" << endl;
    functionThread.join();

    system("pause");
    return 0;
}

我得到以下输出:

Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5
Iteration 6
Iteration 7
Iteration 8
Iteration 9
Changed boolean variable value

我想要的是只对 function_only 进行 1 或 2 次迭代(因此让 main 使用互斥锁)。我怎样才能做到这一点 ?我听说过std::condition_variable,但我想不出一种方法来制作我想要的东西。

此外,如果 doSomething() 未注释并且需要很长时间才能返回,是否有一种简单的方法可以杀死线程或强制它加入而不修改 doSomething 函数中的内容?

【问题讨论】:

  • 你能展示一下你用std::condition_variable做了什么吗?它应该是你想要使用的。
  • Volatile 不适用于多线程目的 (stackoverflow.com/questions/35345899/…)。
  • 现在线程可以在主线程到达mtx.lock()之前完成运行function_的所有迭代。
  • 你读过std::condition_variable的文档吗?应该很容易扩展这个例子,让它做你想做的事。你只需要一个停止标志和一个工作线程中的循环。
  • 不要使用lockunlock。酌情使用std::unique_lockstd::lock_guard

标签: c++ multithreading c++11 visual-c++


【解决方案1】:

您不需要所有这些机制。 atomic&lt;bool&gt;join 就足够了。

不要使用lockunlock。酌情使用unique_locklock_guard

请勿使用volatile,除非您正在处理内存映射硬件或 unix 信号处理程序。

剧透----

#include <thread>
#include <mutex>
#include <iostream>
#include <chrono>
#include <atomic>

using namespace std;  // Kids, don't try this at home.

using stopper = atomic<bool>;

void function_( stopper *ptrStop) {
    for (int i = 0; i < 10; i++) {
        if (*ptrStop) {
            break;
        }
        //doSomething();
        this_thread::sleep_for(chrono::milliseconds(10));
        cout << "Iteration " << i << endl;
        //this_thread::sleep_for(chrono::milliseconds(1));
    }
    *ptrStop = false;
    return;
}


int main() {
    stopper stop{ false };
    thread functionThread(function_, &stop);

    this_thread::sleep_for(chrono::milliseconds(100));

    stop = true;
    // // The following is optional
    ///while (stop == true) {
    //    this_thread::yield();
    //}
    cout << "Changed boolean variable value" << endl;
    functionThread.join();

    return 0;
}

【讨论】:

  • 这正是我想要的,我认为这会更复杂。谢谢
【解决方案2】:

我只是要回答这个问题:

此外,如果 doSomething() 未注释并且需要很长时间 返回,有没有一种简单的方法可以杀死线程或强制它加入 不修改 doSomething 函数中的内容?

答案是否定的。如果你试图以任何方式杀死线程,你不能确定它是在对其他线程无害的时候被杀死的。例如;您的 c++ 库可以使用互斥锁实现 new;如果您在线程被杀死时正在创建新对象;互斥锁将永远保持锁定;使所有其他线程无法调用新线程。这将导致您的程序以您永远无法调试的方式死锁。

您可以可靠地做到这一点的唯一方法是在doSomething() 中做一些工作;然后看看你是否可以回去做更多的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多