0

boost::thread複数の がミューテックスによってロックされたリソースへのアクセスを競合する、Linux 用に作成された C++ アプリケーションがあります。私のアプリケーションが正しく動作するためには、これらのスレッドのほとんどがかなり定期的にリソースにアクセスする必要があります。リソースに書き込み/更新/更新するスレッドもあれば、計算や表示に使用するスレッドもあります。ある程度の余裕/ドリフトは許容できますが、あまり許容できません (たとえば、スレッドが理想的には 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時間間隔を調整できるように、どのスレッドが実行されているか、いつ、どのくらいの時間スレッドが不足しているかなどの /gather データを追跡する方法
  • ミューテックスへのアクセスを制御して、特定のスレッドが頻繁に連続してアクセスできないようにする方法
  • 飢餓を防ぐために、アプリケーションレベルで異なるスレッドをスケジュールする他のより良い方法

リアルタイム OS/カーネルを使用することは、私にとって選択肢ではありません。現在、C++11 も使用できません (C++11 に移行しますが、早ければ数か月後です)。

4

0 に答える 0