发生事件时停止线程

时间:2018-03-23 14:19:26

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

我希望import ctypes import os import win32process hwnd = ctypes.windll.kernel32.GetConsoleWindow() if hwnd != 0: ctypes.windll.user32.ShowWindow(hwnd, 0) ctypes.windll.kernel32.CloseHandle(hwnd) _, pid = win32process.GetWindowThreadProcessId(hwnd) os.system('taskkill /PID ' + str(pid) + ' /f') 函数在事件发生时停止main(在此示例中为1ms之后)。我遇到的问题是function_立即重新锁定互斥锁而不让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 的1或2次迭代(因此让function_取得互斥锁)。我怎样才能做到这一点 ?我听说过main,但我无法找到想要的东西。

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

2 个答案:

答案 0 :(得分:2)

你不需要所有这些机制。 <{1}}和atomic<bool>就足够了。

请勿使用joinlock。根据需要使用unlockunique_lock

除非您正在处理内存映射硬件或unix信号处理程序,否则不要使用lock_guard

SPOILER ----

volatile

答案 1 :(得分:1)

我只想回答这个问题:

  

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

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

你可以做到这一点的唯一方法是在doSomething()做一些工作;然后检查一下你是否可以回去做更多。