簡體   English   中英

多線程代碼 - 強制執行順序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM