1

这个方法(我意识到这个函数可能需要一些额外的参数):

void waitUntilNotEqual(volatile int* addr, int value)
{
    while (*addr == value) {}
}
4

2 回答 2

0

请参阅手册页:http ://ds9a.nl/futex-manpages/futex2.html并让我们知道在那之后您是否还需要一些东西。从您的问题中我不确定的一件事是您是否打算使用另一个函数来通知该值已更新,或者您是否更喜欢使用超时。

于 2012-01-14T16:58:09.340 回答
0

我对使用 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_MAXFUTEX_WAKE表明它应该唤醒所有在这个 futex 上等待的线程。函数中的 if 语句changeValue是一种避免无意义唤醒的优化。最后,FUTEX_WAIT调用需要保持在循环中,因为它可能会从信号中虚假返回。

我还应该指出,您没有提供有关您要解决的问题的太多详细信息,这意味着这段代码可能仅适用于最简单的用例。如果您想要更好地适应您当前的问题,那么我需要更多详细信息(线程数、调用waitUntilNotEqualand的上下文、 orchangeValue中可能的并发线程数等)waitUntilNotEqualchangeValue

如果您有兴趣了解有关如何正确使用 futexes 的更多信息,我推荐Futexes Are Tricky论文。

于 2012-01-14T20:29:27.370 回答