boost线程的用户级调度和跟踪 我有一个C++编写的应用程序,其中多个 Boo::线程< /C> >竞争以访问互斥锁所锁定的资源。为了让我的应用程序正常工作,这些线程中的大多数都需要以相当固定的时间间隔访问资源。一些线程写入/刷新/更新资源,而另一些线程将其用于计算或显示。我可以容忍一些回旋/漂移,但不能容忍太多(例如,如果一个线程最好每隔0.2秒访问一个资源,我可以偶尔再等待0.1秒)

boost线程的用户级调度和跟踪 我有一个C++编写的应用程序,其中多个 Boo::线程< /C> >竞争以访问互斥锁所锁定的资源。为了让我的应用程序正常工作,这些线程中的大多数都需要以相当固定的时间间隔访问资源。一些线程写入/刷新/更新资源,而另一些线程将其用于计算或显示。我可以容忍一些回旋/漂移,但不能容忍太多(例如,如果一个线程最好每隔0.2秒访问一个资源,我可以偶尔再等待0.1秒),c++,multithreading,boost,scheduling,C++,Multithreading,Boost,Scheduling,我在下面给出了一个小例子: 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); ComputeUsingCo

我在下面给出了一个小例子:

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); 
}
对坐标//一些共享资源(实际上更复杂)
boost::互斥锁m//互斥体控制对资源的访问
void Func1(){
而(1){
usleep(1.0*1e6);
boost::作用域锁定sl(m);
计算坐标(坐标);
}
}
void Func2(){
而(1){
usleep(1.2*1e6);
pair newCoords=getCoordinatesCrossNetwork();//远程接收更新
boost::作用域锁定sl(m);
坐标=newCoords;//更新坐标的局部值
}
}
void Func3(){
而(1){
usleep(0.5*1e6);
boost::作用域锁定sl(m);
绘制(坐标);//在屏幕上绘制坐标
}
}
无效计算(){
而(1){
//其他一些计算不访问公共资源,但仍在竞争CPU
}
}
int main(){
boost::thread1=boost::thread(Func1);
boost::thread2=boost::thread(Func2);
boost::thread3=boost::thread(Func3);
//…其他线程不访问资源
boost::thread4=boost::thread(其他计算);
}
目前,我看到一些线程正处于饥饿状态。为了缓解这个问题,我强制每个线程在连续访问资源之间休眠。通过让不同的线程在不同的时间睡眠,我实施了一种特殊的调度策略。当有少量线程时,这似乎工作得很好,但是当我将线程添加到应用程序的不同部分时,饥饿问题似乎越来越频繁地出现

是否有:

  • 一种跟踪/收集正在运行的线程的数据的方法,以及何时、线程不足的时间长度等,以便我可以调整
    usleep
    时间间隔
  • 一种控制对互斥体的访问的方法,使给定线程不能频繁地连续访问互斥体
  • 还有一些更好的方法可以在应用程序级别调度不同的线程,以防止饥饿

使用实时操作系统/内核不是我的选择。目前,我也不能使用C++11(我们将迁移到C++11,但最早只能在几个月后使用)。

所有操作(计算、绘制等)在运行时都需要所有坐标数据吗?它们是否都会改变坐标数据?如果是,它们是否总是需要访问所有坐标数据?问题是,锁最好保持简短,而您的锁似乎不适合该类别:)请提供更多详细信息。基于优先级的线程池可以为调度策略和逻辑提供单一位置,并提供执行跟踪、防止连续访问的能力,等。操作将通过线程池进行调度,而不是专用于给定的线程。这种方法的转变也可能揭示出可以避免争用的领域。例如,计算操作只需要在执行receive时进行调度,或者如果尚未计算新坐标,则绘制操作可以使用缓存的坐标。@读取坐标数据的所有操作(计算、绘制等)都会读取坐标数据。改变数据的操作(目前,只有Func2通过网络接收更新并更新本地副本)通常不会改变所有数据,但它们可以根据发送数据的频率进行改变。我同意短锁的说法。我的经验法则是锁定尽可能粗的颗粒,然后根据需要进行细化。我想我已经到了那个地步。@TannerSansbury我说线程池对于线程不断开始和完成的场景更有用,对吗?我认为,线程池只是为了减轻线程创建的开销。我的场景有点不同——大多数线程都是在程序开始时创建的,并持续整个生命周期(10-15分钟)。当我说“将线程添加到应用程序的不同部分”时,我的意思是在我的代码中添加越来越多的内部使用线程的对象。如果顺序特别重要,或者如果随机选择一个顺序会起作用,您是否考虑过使用boost条件变量?根据设置方式,您可以让它根据多个条件(主要是if语句)随机选择下一个线程,或者将其设置为当一个线程结束时,将调用预制“圆”上的下一个线程。