多线程代码 - 强制执行顺序

时间:2009-01-20 14:46:26

标签: multithreading locking

我有一些代码可以从两个线程访问:


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()方法时被抓取的互斥锁来解决...并且在read()方法中检查running_之前被抓取......但似乎有点不必要。如果这里的所有内容按顺序执行,那么就没有问题。我没有问题,当另一个线程在Start()路由中时可能发生Read(),例如从时钟获取时间...... Read()s发生得足够快,它只是不是a很重要。

无论如何,我一直在寻找一种方法来确保编译器/处理器执行

  start_ = clock_->GetCurrentTime();
  running_ = true;

说明按顺序列出如上。 (或者,如果我忽略了别的东西)。

4 个答案:

答案 0 :(得分:3)

您需要制作start_和running_ volatile,然后在Start()中的两个作业之间引入内存障碍。

答案 1 :(得分:1)

为什么不摆脱“running”标志并使用“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_;
};

答案 2 :(得分:0)

我不确定我是否理解你的问题,但我认为你想要防止在没有设置Start方法(或者还没有完全执行)时执行Read?

如果是这种情况,你不能通过使用AutoResetEvent或ManualResetEvent解决问题(取决于你想要的行为)。

在Read方法中,您可以指定在未设置Auto / ManualResetEvent时Read方法应该等待,并且在Start方法结束时,您可以设置Event。

答案 3 :(得分:0)

为什么不坚持

if (_running == false) Start();

在Read()方法中。 并使用互斥锁保护启动或将其定义为“关键”以确保其单线程。