我有一个为 Linux 编写的 C++ 应用程序,其中多个boost::thread
s 竞争访问由互斥锁锁定的资源。为了让我的应用程序正常工作,这些线程中的大多数都需要定期访问资源。一些线程写入/刷新/更新资源,而其他线程将其用于计算或显示。我可以容忍一些余地/漂移,但不能太多(例如,如果一个线程理想情况下应该每 0.2 秒访问一次资源,我可以偶尔再等待 0.1 秒)。
我在下面给出了一个小例子:
pair<int,int> coordinates; //some shared resource (more complex in reality)
boost::mutex m; //mutex controlling access to resource
void Func1() {
while(1) {
usleep(1.0*1e6);
boost::scoped_lock sl(m);
ComputeUsingCoordinates(coordinates);
}
}
void Func2() {
while(1) {
usleep(1.2*1e6);
pair<int,int> newCoords = GetCoordinatesAcrossNetwork(); //receives update remotely
boost::scoped_lock sl(m);
coordinates = newCoords; //update local value of coordinates
}
}
void Func3() {
while(1) {
usleep(0.5*1e6);
boost::scoped_lock sl(m);
Draw(coordinates); //draws coordinates on a screen
}
}
void OtherComputation () {
while(1) {
//Some other computation that doesn't access the common resource, but is nevertheless competing for the CPU
}
}
int main() {
boost::thread thread1 = boost::thread(Func1);
boost::thread thread2 = boost::thread(Func2);
boost::thread thread3 = boost::thread(Func3);
// ... other threads not accessing the resource
boost::thread thread4 = boost::thread(OtherComputation);
}
目前,我看到一些线程正在被饿死。为了缓解这个问题,我强制每个线程在对资源的连续访问之间休眠。通过让不同的线程休眠不同的时间,我实施了一个临时调度策略。当线程数量很少时,这似乎工作得很好,但是当我将线程添加到应用程序的不同部分时,饥饿问题似乎越来越频繁地出现。
在那儿:
- 一种跟踪/收集关于哪些线程正在运行的数据的方法,以及何时、多长时间的线程饥饿等,以便我可以调整
usleep
时间间隔 - 一种控制对互斥体的访问的方法,以便给定线程不能过于频繁地连续访问它
- 在应用程序级别安排不同线程以防止饥饿的其他更好方法
使用实时操作系统/内核对我来说不是一个选择。目前,我也不能使用 C++11(我们将迁移到 C++11,但最早也只有几个月的时间)。