![](/img/trans.png)
[英]ConcurrentHashMap method execution order in multithreaded environment
[英]Multithreaded code - force execution order
我有一些代碼可以從兩個線程訪問:
class Timer{
public:
void Start(){
start_ = clock_->GetCurrentTime();
running_ = true;
}
void Read(){
if(running_){
time_duration remaining = clock_->GetCurrentTime() - start_;
Actions(remaining)
}
}
private:
void Actions(time_duration remaining);
time start_;
bool running;
};
我看過各種庫中可用的其他計時器,但沒有找到任何符合我要求的計時器,因此我自己動手...
從一個線程調用Start()方法(僅一次)。 從另一個線程非常快速地調用Read()方法,調用將在調用Start()之前開始調用。
顯然,在設置running_flag 之前初始化start_變量非常重要。 這可以通過添加一個在進入Start()方法時被抓取的互斥鎖來解決...並且在read()方法中檢查running_之前被抓取......但似乎有點不必要。 如果這里的所有內容按順序執行,那么就沒有問題。 我沒有問題,當另一個線程在Start()路由中時可能發生Read(),例如從時鍾獲取時間...... Read()s發生得足夠快,它只是不是a很重要。
無論如何,我一直在尋找一種方法來確保編譯器/處理器將執行
start_ = clock_->GetCurrentTime();
running_ = true;
說明按順序列在上面。 (或者,如果我忽略了別的東西)。
您需要創建start_和running_ volatile
,然后在Start()
的兩個賦值之間引入內存屏障。
為什么不擺脫“運行”標志並使用“start”變量是否為空狀態? 你沒有指定一種語言,但“開始”的某種易變標記也是一個好主意。 這也假設“開始”可以原子方式編寫。 例如:
class Timer{
public:
void Start(){
start_ = clock_->GetCurrentTime();
}
void Read(){
if(nullptr != start_){
time_duration remaining = clock_->GetCurrentTime() - start_;
Actions(remaining)
}
}
private:
void Actions(time_duration remaining);
volatile time start_;
};
我不確定我是否理解你的問題,但我認為你想要防止在沒有設置Start方法(或者還沒有完全執行)時執行Read?
如果是這種情況,您不能通過使用AutoResetEvent或ManualResetEvent(取決於您想要的行為)來解決您的問題。
在Read方法中,您可以指定Read方法在未設置Auto / ManualResetEvent時應等待,並且在Start方法結束時,您可以設置Event。
為什么不堅持一個
if (_running == false) Start();
在Read()方法中。 並使用互斥鎖保護啟動或將其定義為“關鍵”以確保其單線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.