Boost
マルチスレッドBoost
アプリケーションを作成してWindowsまたはLinuxでコンパイルできることを知っているので、私はスレッドを試してpthreads
います.
別の SO question から借用した次のサンプル アプリケーションがあります。
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>
#define NAP_DURATION (10000UL) // 10ms
boost::mutex io_mutex;
void count(int id)
{
for (int i = 0; i < 1000; ++i)
{
boost::mutex::scoped_lock lock(io_mutex);
std::cout << "Thread ID:" << id << ": " << i << std::endl;
if (id == 1)
{
std::cout << "I'm thread " << id << " and I'm taking a short nap" << std::endl;
usleep(NAP_DURATION);
}
else
{
std::cout << "I'm thread " << id << ", I drink 100 cups of coffee and don't need a nap" << std::endl;
}
std::cout << "Thread ID:" << id << ": " << i << std::endl;
boost::thread::yield();
}
}
int main(int argc, char* argv[])
{
boost::thread thrd1( boost::bind(&count, 1));
boost::thread thrd2( boost::bind(&count, 2));
thrd1.join();
thrd2.join();
return 0;
}
次の方法で、Ubuntu 14.04 LTS システムに Boost をインストールしました。
sudo apt-get install libboost-all-dev
そして、次の方法で上記のコードをコンパイルします。
g++ test.cpp -lboost_system -lboost_thread -I"$BOOST_INLCUDE" -L"$BOOST_LIB"
いくつかの興味深い矛盾のように見えるものに出くわしました。longy NAP_DURATION
、たとえば 1 秒 ( ) を設定すると、操作が完了するまで1000000
スレッドのみがミューテックスを取得するように見えます。スレッドが完了するまでスレッドがロックを取得することは非常にまれです。数ミリ秒。1
2
1
NAP_DURATION
を使用して同様のアプリケーションを作成しpthreads
た場合、別のスレッドがミューテックスで既にブロックされているため、通常、ロックはスレッド間で多かれ少なかれランダムに交互に行われます。
それで、質問に:
- これは予想される動作ですか?
- ロック操作がキューに入れられたようにスコープ ロックを動作させるなど、この動作を制御する方法はありますか?
- (2) に対する答えが「いいえ」の場合、条件変数を使用して同様のことを達成し
Boost
、ロック/ロック解除の呼び出しが失敗することを心配する必要はありませんか? scoped_lock
ロック解除は保証されていますか?どうやらロック解除操作が失敗して例外をスローする可能性があるため、手動でロック/ロック解除するのではなく、RAII アプローチを使用しています。このコードを確実なものにしようとしています。
ありがとうございました。
明確化
呼び出しスレッドをスリープ状態にしてもミューテックスのロックが解除されないことは承知していますが、それはまだスコープ内にあるためですが、予想されるスケジューリングは次のようなものでした。
- Thread1 がロックし、mutex を取得します。
- Thread2 のロック、ブロック。
- Thread1 が実行され、ロックが解放され、すぐに再度ロックが試行されます。
- スレッド 2 は既にロックを待機しており、スレッド 1 の前にロックを取得します。