我如何使用 futex 来实现这个方法?

发布于 2024-12-27 03:59:02 字数 146 浏览 4 评论 0原文

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

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

This method (I realize the function might need some extra parameters):

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蒗幽 2025-01-03 03:59:02

请参阅手册页:http://ds9a.nl/futex-manpages/futex2.html 如果之后您还需要什么,请告诉我们。从你的问题中我不确定的一件事是你是否打算有另一个函数来通知这个值已经更新,或者你是否更喜欢使用超时。

See the man page: http://ds9a.nl/futex-manpages/futex2.html and let us know if there's something you still need after that. One thing I am not sure of from your question is whether you intend to have another function that informs this one that the value has been updated, or if you prefer to use timeouts.

尝蛊 2025-01-03 03:59:02

我对 futexes 的使用还很陌生,但这里有一个我认为应该可行的解决方案。请注意,我根本没有对此进行测试,通过更多的调整可以使其速度更快。

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 完成。 FUTEX_WAKE 调用中的 INT_MAX 值指示它应该唤醒等待此 futex 的所有线程。 changeValue 函数中的 if 语句是一种优化,可以避免无意义的唤醒。最后,FUTEX_WAIT 调用需要保持在循环中,因为它可能会从信号中虚假返回。

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

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

I'm pretty new to the use of futexes but here's a solution that I think should work. Just be warned that I haven't tested this at all and it could be made faster with a few more tweaks.

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);
  }
}

In order for this to work properly, all modification of the address passed to waitUntilNotEqual should be done through changeValue. The INT_MAX value in the FUTEX_WAKE call indicates that it should wake all threads waiting on this futex. The if statement in the changeValue function is an optimisation that avoids pointless wakeups. Finally, the FUTEX_WAIT call needs to be kept in a loop because it might return spuriously from signals.

I should also point out that you didn't give much details about the problem you're trying to solve which means that this piece of code is probably only correct for the very simplest of use cases. If you want something better adapted to your current problem then I need more details (number of threads, context in which waitUntilNotEqual and changeValue is called, number of possible concurrent threads in waitUntilNotEqual or changeValue, etc.)

If you're interested in learning more about how to properly use futexes, I recommend the Futexes Are Tricky paper.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文