この方法(関数には追加のパラメーターが必要になる場合があることに気づきました):
void waitUntilNotEqual(volatile int* addr, int value)
{
while (*addr == value) {}
}
man ページを参照してください: http://ds9a.nl/futex-manpages/futex2.htmlその後、まだ必要なものがある場合はお知らせください。あなたの質問から私が確信していないことの1つは、値が更新されたことをこの機能に通知する別の機能を使用するつもりなのか、それともタイムアウトを使用したいのかということです。
私はfutexの使用にかなり慣れていませんが、これがうまくいくと思う解決策です。私はこれをまったくテストしていないことに注意してください.
void waitUntilNotEqual(volatile int* addr, int value) {
while (*addr == value) {
futex(addr, FUTEX_WAIT, value, 0, 0, 0);
}
}
void changeValue (volatile int* addr, int newValue) {
int oldValue = *addr;
if (oldValue != newValue) {
*addr = newValue;
futex(addr, FUTEX_WAKE, INT_MAX, 0, 0, 0);
}
}
これが適切に機能するためには、 に渡されるアドレスのすべての変更をwaitUntilNotEqual
を通じて行う必要がありますchangeValue
。呼び出しのINT_MAX
値は、FUTEX_WAKE
この futex で待機しているすべてのスレッドをウェイクアップする必要があることを示しています。関数内の if ステートメントは、changeValue
無意味な wakeup を回避する最適化です。最後に、FUTEX_WAIT
呼び出しはシグナルから誤って返される可能性があるため、ループ内に保持する必要があります。
また、解決しようとしている問題について詳しく説明していないことも指摘しておく必要があります。つまり、このコードは、おそらく最も単純なユース ケースに対してのみ正しいということです。現在の問題により適したものが必要な場合は、詳細が必要です (スレッドの数、waitUntilNotEqual
andが呼び出されるコンテキスト、 orchangeValue
で可能な同時スレッドの数など)。waitUntilNotEqual
changeValue
futex を適切に使用する方法について詳しく知りたい場合は、Futex はトリッキーな論文をお勧めします。