【发布时间】:2021-03-05 03:06:28
【问题描述】:
所以我的程序中有 2 个线程在运行,我最终希望它们在调用此函数时终止:
void AutoClicker::TerminateThreads()
{
programrunning = false;
clicker.join();
hotkeyLoop.join();
terminateThread = true;
}
然后调用线程应该运行这段代码:
while (1)
{
while (programrunning)
{
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}
if (terminateThread) {
std::terminate();
}
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
但最后一个if 语句似乎没有被调用。它位于我试图终止的线程内,所以它应该可以正常工作吗?我对线程很陌生,所以我真的不知道该怎么做,但这是我在网上找到的:
“当
std::thread对象被销毁时,它不允许被joinable(),即在它被销毁之前必须发生两件事之一:
它被分离了,线程已经进入野外,几乎无法控制它是否完成。
话题已经
join()ed。"
【问题讨论】:
-
如果这是真正的代码,您无法保证线程会看到对
programrunning的更改,因为没有任何类型的同步。更糟糕的是,一个线程可能会访问programrunning,而另一个线程正在修改它,这可能会被您编码的任何线程标准所禁止。 (C++ 标准禁止这样做,除非programrunning是std::atomic或其他我们无法分辨的东西。) -
对不起,我对线程很陌生,但是我将如何同步程序运行,因为我还在另一个函数中更改它,如果按下热键,它会显示,如果是,则切换程序运行变量并且工作正常
-
假设您使用的是 C++ 标准线程,您必须遵循它们的规则。 C++ 标准(在第 1.10 节中)说具有数据竞争的程序表现出未定义的行为。您的程序存在数据竞争,因为一个线程可以在另一个线程访问它的同时修改
programrunning。您根本不允许这样做。 “本国际标准对包含未定义行为的程序的行为没有任何要求。......任何此类数据竞争都会导致未定义行为。”你不能让线程互相践踏,必须协调它们。 -
(如果
programrunning是std::atomic,则忽略上述内容,因为它的内部同步不允许两个操作同时发生,因此不会是数据竞争。) -
从代码中不清楚,但如果
while循环作为第一个代码 sn-p 中加入的线程之一的一部分运行,则while中的代码循环不会看到对terminateThread的更改。对join()的调用都会阻塞,直到相应的线程结束,所以分配来得太晚了。
标签: c++ multithreading visual-studio terminate