【发布时间】:2020-09-16 12:58:36
【问题描述】:
我有 2 个线程监视同一个全局 state,如果 state.shutdown 变为 false,则线程 run() 应该返回。代码如下。
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
using namespace std;
struct State {
bool shutdown = false;
~State() {
shutdown = true;
}
};
State state;
#define CHECK_SHUTDOWN \
{ \
std::cout << (state.shutdown ? " SHUTDOWN " : " NOSHUT ") << typeid(*this).name() << std::endl; \
if (state.shutdown) { \
return; \
} \
}
class Mythread {
public:
void join();
void run();
void launch();
std::thread self_thread;
};
void Mythread::run() {
while(1) {
CHECK_SHUTDOWN
}
}
void Mythread::join() {
if (self_thread.joinable()) {
self_thread.join();
}
}
void Mythread::launch() {
self_thread = std::thread(&Mythread::run, this);
}
std::mutex mtx;
void shut() {
std::lock_guard<std::mutex> lock(mtx);
state.shutdown = true;
}
int main()
{
Mythread thread1;
Mythread thread2;
thread1.launch();
thread2.launch();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//state.shutdown = true;
shut(); //This makes no difference with the line above
std::this_thread::sleep_for(std::chrono::milliseconds(100));
thread1.join();
thread2.join();
return 0;
}
但是,即使我手动将 state.shutdown 设置为 true,线程也永远无法检测到它。我得到了这样的打印:
NOSHUT 8Mythread
NOSHUT 8Mythread
NOSHUT 8Mythread
...Program finished with exit code 0
Press ENTER to exit console.
最后。我也很困惑,因为永远不会返回 run() 函数,线程连接应该挂起。但是线程可以成功加入。
任何帮助将不胜感激!
【问题讨论】:
-
欢迎来到“sequencing”这个精彩的话题,这是一组规则,指定线程如何“看到”来自其他线程的对象的变化。这需要 两个 线程、更改对象的线程和“看到”对象的线程采取特定的、显式的操作。规则很复杂,无法在 stackoverflow.com 上的一两段中完全概括,除非过于简化并遗漏了一堆细节。如果您真的想正确学习该主题,请参阅您的 C++ 教科书对该主题的冗长讨论。
-
简单的解决方法是将
State::shutdown设置为std::atomic<bool>,但听从Sam 的建议并阅读为什么这是必要的,你会得到很好的服务。 -
@SamVarshavchik 感谢您的回复。你能指点我任何在线资源吗?我在我的 C++ 入门书(第 4 版)中找不到它。
标签: c++ multithreading global-variables mutex