我有一些代码可以从两个线程访问:
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;
说明按顺序列出如上。 (或者,如果我忽略了别的东西)。
答案 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()方法中。 并使用互斥锁保护启动或将其定义为“关键”以确保其单线程。