参照に従ってLinuxでIPCを実行しています(匿名ミューテックスの例)。boost::interprocess::shared_memory_object
でラップされた;shared_memory_object
を保持しながら、 を作成して書き込むサーバープロセスがあります。そして、他の人が書いたものは何でも印刷するクライアントプロセス - この場合、それは.interprocess_mutex
scoped_lock
int
問題が発生しました。サーバーがミューテックスを保持している間にスリープ状態になると、クライアント プロセスはミューテックスを取得できず、永遠に待機します。
バグのあるサーバーループ:
using namespace boost::interprocess;
int n = 0;
while (1) {
std::cerr << "acquiring mutex... ";
{
// "data" is a struct on the shared mem. and contains a mutex and an int
scoped_lock<interprocess_mutex> lock(data->mutex);
data->a = n++;
std::cerr << n << std::endl;
sleep(1);
} // if this bracket is placed before "sleep", everything works
}
サーバー出力:
acquiring mutex... 1
acquiring mutex... 2
acquiring mutex... 3
acquiring mutex... 4
クライアントループ:
while(1) {
std::cerr << "acquiring mutex... ";
{
scoped_lock<interprocess_mutex> lock(data->mutex);
std::cerr << data->a << std::endl;
}
sleep(1);
}
クライアント出力 (永久に待機):
acquiring mutex...
問題は、ブラケットをsleep
呼び出しの前の行に移動すると、すべてが機能することです。なんで?ロックされたミューテックスでスリープすると、ミューテックスが永久にロックされるとは思いませんでした。
私が持っている唯一の理論は、カーネルがサーバー プロセスを起動すると、スコープが終了し、ミューテックスが解放されるが、待機中のプロセスには実行の機会が与えられないというものです。その後、サーバーはロックを再取得します...しかし、それはあまり意味がないようです。
ありがとう!