回調設置類成員,我有下面的類,允許通過昂貴的計算設置一個值,我們可以假裝計算異步發生在其他線程。該類還有一個方法,如果需要得到的電流值,也許這樣做計算同步:與線程安全的方式
class Example {
public:
Example() : x_(0) {}
void Set(int x) {
SomeOtherFunc(x, callback_, false);
}
void Finished(int y) {
x_ = y;
}
const int Get() {
if (!x_) {
SomeOtherFunc(1, callback_, true);
}
return x_;
}
private:
int x_;
std::function<void(int)> callback_ =
std::bind(&Example::Finished, this, std::placeholders::_1);
};
而且讓我們假裝這個功能:
void SomeOtherFunc(int x, const std::function<void(int)>& func,
bool blocking) {
// Do something expensive, in another thread, possibly blocking.
func(x * 2);
}
這樣的工作方式,我想:
Example e1, e2;
e1.Set(5);
// "10 2"
std::cout << e1.Get() << " " << e2.Get();
我關注的是如下情況:
Example e;
e.Set(10); // Takes a while
e.Get(); // Need the value now
個
我的問題:
- 是在
Example
類線程安全的?如果不是的話,怎麼會這樣呢?看起來像鎖會起作用,但可能是矯枉過正。 - 由於
SomeOtherFunc
的工作很貴,我只想調用一次這個函數。在類內部設置一個標誌,每當調用被創建時被設置爲true,並且在調用之前被檢查,這似乎是合理的(但它是否是線程安全的?)。問題是,如果我叫Set
,然後Get
隨即,我想Get
爲x_
返回「最終」值。我如何確保?也就是說,如果設置了該標誌,我該如何讓Get
等待回調以線程安全的方式完成?
因此,如果一個調用正在進行,call_once會在'Get()中阻塞?這幾乎就是我想要的。 –
@SteveD是的,這是'call_once'保證的。對於'Get()'(和'Set()')的所有(併發)調用將會阻止,如果當SomeOtherFunc()無論是由'Get()'還是'Set()'啓動' – LWimsey
再次感謝,這正是我所需要的 –