(更新:我有一些好主意,尝试在答案和评论-要开始尝试的东西,这周和更新时,再次工作!)
这是一个我已经挣扎了一段时间。我有一个C++类,它有许多公共函数,并且期望这些函数中的每一个都将定期从不同的线程调用。类的基本形式是这样的:
class DataProcessor
{
public:
void process1(...);
void process2(...);
void process3(...);
// etc...
void update();
};
这是一个机器人应用程序,每个“进程”函数都用于接收来自不同传感器的数据,因此每当新的传感器数据进来时,我们都会在自己的线程中调用相应的“进程”函数。“update”函数在一个循环中使用,看起来像这样:
while(true) {
wait 1 second;
dataProcessor.update();
}
现在,我已经设置好了,这样每个“进程”函数都可以被并发调用而没有任何问题,但是“更新”函数不应该在任何“进程”函数执行时被调用。更新函数相当快,几乎不需要任何时间就能执行,而一些进程函数比较昂贵,可能会达到0的数量级。1-0.2秒。
到目前为止,我已经尝试了两种策略来使其安全执行,但这两种策略都导致函数花费太多时间阻塞/等待互斥锁(“互斥锁”?)解锁。
我能做的第一件事是让每个“进程”函数在执行的开始和结束时锁定和解锁自己的互斥体,然后“更新”函数必须拥有所有互斥体才能执行。当我这样做时,我会遇到以下问题:
1.“process 1”函数完成并解锁互斥锁1
- update函数锁定mutex 1,并等待mutex 2被解锁
1.再次调用“procees 1”函数,但必须等待update函数解锁mutex 1 - update函数在完成执行之前不能解锁mutex 1,因为它正在等待所有其他“进程”函数完成
因此,现在“process 1”函数实际上必须等待所有其他“process”函数完成,即使这些进程函数被设计为能够并发运行。
所以另一个策略是使用计数器。基本上是一个“numberOfFunctionsRunning”变量,因此每个“process”函数可以在开始时递增变量,并在结束时递减。然后update函数只能在变量为零时执行。这稍微好一点,因为现在流程函数可以再次并发执行,但现在更新函数永远等待,因为变量很少达到零。
所以,是的,我希望这是足够的信息,这是有意义的,我想做的事情。有没有什么线程策略可以用来确保“进程”函数可以执行而不需要花费大量的时间等待,同时还可以确保更新函数可以定期执行?
1条答案
按热度按时间yqlxgs2m1#
您可以使用std::lock以原子方式锁定所有互斥锁,如下所示:
这样,
void update()
中的锁只有在其他函数都没有持有锁时才会生效,从而避免了死锁。