2

boost :: timed_lock

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 

boost::timed_mutex mutex; 

void thread() 
{ 
  for (int i = 0; i < 5; ++i) 
  { 
    wait(1); 
    boost::unique_lock<boost::timed_mutex> lock(mutex, boost::try_to_lock); 
    if (!lock.owns_lock()) 
      lock.timed_lock(boost::get_system_time() + boost::posix_time::seconds(1));//<<<<
    std::cout << "Thread " << boost::this_thread::get_id() << ": " << i << std::endl; 
    boost::timed_mutex *m = lock.release(); 
    m->unlock(); 
  } 
}

timed_lock

質問>次の行を理解するのに問題があります。

  if (!lock.owns_lock()) 
     lock.timed_lock(boost::get_system_time() + 
                     boost::posix_time::seconds(1));//<<<<

これが私の理解です。falseを返すと仮定lock.owns_lock()します。これは、現在のオブジェクトがロック可能なオブジェクトのロックを所有していないことを意味します。したがって、次の行が実行されます。指定された時間が経過してもオブジェクトがロックを取得できない場合、boost::timed_lockはfalseを返します。したがって、次の行が実行されます???

std::cout << "Thread " << boost::this_thread::get_id() << ": " << i << std::endl; 

この考えは正しいですか?コードの目的は、オブジェクトにロックがある場合に上記の行が実行されることを確認することだと思います。しかし、私の理解に基づいて(私は正しくないと思います)、上記の行は常に実行されます!

問題はどこだ?

4

2 に答える 2

3

あなたは正しいです。この例は、保護されたコードを実行する前にロックが常に適切に取得されることを保証するものではありません。

以下の例の説明を考えると:

上記のプログラムは、boost::try_to_lockを2番目のパラメーターとしてboost::unique_lockのコンストラクターに渡します。ミューテックスが取得されているかどうかは、後でowns_lock()メソッドを使用して確認できます。ない場合-owns_lock()はfalseを返します-boost :: unique_lockによって提供される別の関数が使用されます:timed_lock()はミューテックスを取得するために特定の時間待機します。指定されたプログラムは最大1秒待機します。これは、ミューテックスを取得するのに十分な時間以上である必要があります。

この例は、実際にミューテックスを取得する3つの基本的な方法を示しています。lock()は、ミューテックスが取得されるまで待機します。try_lock()は待機しませんが、呼び出し時に使用可能である場合はミューテックスを取得し、それ以外の場合はfalseを返します。最後に、timed_lock()は、指定された期間内にミューテックスを取得しようとします。try_lock()と同様に、成功または失敗は、bool型の戻り値によって示されます。

著者は問題を認識しているように見えますが(ドキュメントの戻り値をtimed_lock考えると)、ロックが取得されているかどうかを再テストする必要があるとは考えていませんでした(「最大1秒待つ必要があります。ミューテックスを取得するのに十分な時間よりも」)。


あなたの理解における1つの誤り:

指定された時間が経過してもオブジェクトがロックを取得できない場合、boost::timed_lockはfalseを返します。

本当じゃない。timed_lock「継続的に」ロックを取得しようとしますが、指定された時間が経過するとあきらめます。

于 2013-01-07T17:19:38.380 に答える
1

あなたが正しいです。この例では、ミューテックスがロックに失敗したときの状態を適切に処理していません。その例のすぐ下をよく読むと、そこに引用されていることがわかります。

上記の例では、さまざまな方法を使用して、boost::unique_lockによって提供される機能の一部を示しています。確かに、これらの機能の使用は、特定のシナリオにとって必ずしも意味がありません。前の例のboost::lock_guardの使用法はすでに適切でした。この例は、boost::unique_lockによって提供される可能性を示すことを目的としています。

于 2013-01-07T17:08:22.153 に答える