抛出的 object 无法被 multi-threaded 解决
Thrown object cannot be caught in a multi-threaded solution
我有一个 RAII class 解决了内部线程中的一个问题:
#include <iostream>
#include <thread>
using namespace std;
struct solution_using_thread {
solution_using_thread()
: alive_(true), thread_() {
thread_ = thread([this]() {
while(alive_);
});
}
~solution_using_thread() {
alive_ = false;
thread_.join();
}
private:
bool alive_;
thread thread_;
};
int main() {
cout << 0 << endl;
try {
solution_using_thread solution;
throw 1;
} catch (int i ) {
cout << i << endl;
}
cout << 2 << endl;
}
在创建了它的一个实例之后,main恰好抛出了一个异常。问题出在某些执行中,输出为:
0
当它总是应该是:
0
1
2
在coliru中总是只有0
.
我在这里错过了什么?
PS:抱歉,标题含糊不清。请不要犹豫,为这个问题提出更好的建议。
您假设线程将(最终)看到 alive_
的更新值。但这并不能保证。没有同步的对象 not 保证在任何有限的时间内对其他线程可见。 alive_
的值可能缓存在某个地方并且永远不会更新。
您需要一些同步才能使其工作——要么使用互斥体或其他同步原语,要么使 alive_
原子化。这是后者的 working example:
#include <atomic>
struct solution_using_thread {
solution_using_thread()
: alive_(true), thread_() {
thread_ = thread([this]() {
while(alive_);
});
}
~solution_using_thread() {
alive_ = false;
thread_.join();
}
private:
atomic<bool> alive_;
thread thread_;
};
没有任何同步,程序有未定义的行为,因为两个线程在 alive_
上进入数据竞争。
我有一个 RAII class 解决了内部线程中的一个问题:
#include <iostream>
#include <thread>
using namespace std;
struct solution_using_thread {
solution_using_thread()
: alive_(true), thread_() {
thread_ = thread([this]() {
while(alive_);
});
}
~solution_using_thread() {
alive_ = false;
thread_.join();
}
private:
bool alive_;
thread thread_;
};
int main() {
cout << 0 << endl;
try {
solution_using_thread solution;
throw 1;
} catch (int i ) {
cout << i << endl;
}
cout << 2 << endl;
}
在创建了它的一个实例之后,main恰好抛出了一个异常。问题出在某些执行中,输出为:
0
当它总是应该是:
0
1
2
在coliru中总是只有0
.
我在这里错过了什么?
PS:抱歉,标题含糊不清。请不要犹豫,为这个问题提出更好的建议。
您假设线程将(最终)看到 alive_
的更新值。但这并不能保证。没有同步的对象 not 保证在任何有限的时间内对其他线程可见。 alive_
的值可能缓存在某个地方并且永远不会更新。
您需要一些同步才能使其工作——要么使用互斥体或其他同步原语,要么使 alive_
原子化。这是后者的 working example:
#include <atomic>
struct solution_using_thread {
solution_using_thread()
: alive_(true), thread_() {
thread_ = thread([this]() {
while(alive_);
});
}
~solution_using_thread() {
alive_ = false;
thread_.join();
}
private:
atomic<bool> alive_;
thread thread_;
};
没有任何同步,程序有未定义的行为,因为两个线程在 alive_
上进入数据竞争。