问题标签 [condition-variable]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
891 浏览

multithreading - What is the fastest race free method for polling a lockless queue?

Say we have a single-producer-thread single-consumer-thread lockless queue, and that the producer may go long periods without producing any data. It would be beneficial to let the consumer thread sleep when there is nothing in the queue (for the power savings and freeing up the CPU for other processes/threads). If the queue were not lockless, the straightforward way to solve this problem is to have the producing thread lock a mutex, do its work, signal a condition variable and unlock, and for the reading thread to lock the mutex, wait on the condition variable, do its reading, then unlock. But if we're using a lockless queue, using a mutex the exact same way would eliminate the performance we gain from using a lockless queue in the first place.

The naive solution is to have the producer after each insertion into the queue lock the mutex, signal the condition variable, then unlock the mutex, keeping the actual work (the insertion into the queue) completely outside the lock, and to have the consumer do the same, locking the mutex, waiting on the condition variable, unlocking it, pulling everything off the queue, then repeat, keeping the reading of the queue outside the lock. There's a race condition here though: between the reader pulling off the queue and going to sleep, the producer may have inserted an item into the queue. Now the reader will go to sleep, and may stay so indefinitely until the producer inserts another item and signals the condition variable again. This means you can occasionally end up with particular items seeming to take a very long time to travel through the queue. If your queue is always constantly active this may not be a problem, but if it were always active you could probably forget the condition variable entirely.

AFAICT the solution is for the producer to behave the same as if it were working with a regular needs-locking queue. It should lock the mutex, insert into the lockless queue, signal the condition variable, unlock. However, the consumer should behave differently. When it wakes, it should unlock the mutex immediately instead of waiting until it's read the queue. Then it should pull as much of the queue as it can and process it. Finally, only when the consumer is thinking of going to sleep, should it lock the mutex, check if there's any data, then if so unlock and process it or if not then wait on the condition variable. This way the mutex is contended less often than it would be with a lockfull queue, but there's no risk of going to sleep with data still left on the queue.

Is this the best way to do it? Are there alternatives?

Note: By 'fastest' I really mean 'fastest without dedicating a core to checking the queue over and over,' but that wouldn't fit in the title ;p

One alternative: Go with the naive solution, but have the consumer wait on the condition variable with a timeout corresponding to the maximum latency you are willing to tolerate for an item traveling through the queue. If the desired timeout is fairly short though, it may be below the minimum wait time for your OS or still consume too much CPU.

0 投票
4 回答
3049 浏览

c++ - 如果在我执行 timed_wait 持续时间时系统时间发生变化怎么办?

在持续时间timed_wait上使用boost::condition_variable时,即使用户(或 ntp)更改系统时间,等待条件是否会在持续时间之后超时?

例如,

0 投票
3 回答
53272 浏览

c++ - 在不锁定互斥锁的情况下调用 pthread_cond_signal

我在某处读到我们应该在调用pthread_cond_signal之前锁定互斥锁并在调用它之后解锁互斥锁:

pthread_cond_signal() 例程用于通知(或唤醒)另一个正在等待条件变量的线程。它应该在互斥锁被锁定后调用,并且必须解锁互斥锁才能完成 pthread_cond_wait() 例程。

我的问题是:不锁定互斥体就可以调用pthread_cond_signalpthread_cond_broadcast方法吗?

0 投票
1 回答
1245 浏览

c++ - 将 pos_infin 作为超时传递给 timed_wait 时,年份超出有效范围

以下代码重现了该错误:

在我的系统上,使用 Visual Studio 2005 和 Boost 1.43,这会产生以下输出:

我希望它会死锁,等待条件变量永远得到通知。这似乎没有在任何地方记录,我也希望timed_wait接受任何有效ptime的 . 我做错什么了吗?这是一个错误,还是不打算无限超时?

0 投票
1 回答
1394 浏览

c - pthread_cond_wait 的空参数

如果一个线程调用 pthread_cond_wait(cond_ptr,mutex_ptr) 将是一个的cond_ptr,它是否保证不会睡着?

根据http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_cond_wait.html,空 cond_ptr 只是意味着 pthread_cond_wait() 可能(不是强调)失败,所以我猜线程可以在空条件下睡着变量?

0 投票
2 回答
4117 浏览

c - 向条件变量发出信号(pthreads)

假设某个条件变量“cond”与互斥变量“mutex”相关联。如果一个线程cond在调用后正在休眠pthread_cond_wait(&cond,&mutex),并且另一个已mutex锁定的线程已完成,那么该线程在调用pthread_cond_signal(&cond)之前还是之后调用是否重要pthread_mutex_unlock(&mutex)?如果它调用,它是否甚至需要解锁互斥锁pthread_cond_signal(&cond),因为睡眠线程无论如何都会获取互斥锁?

编辑:根据https://computing.llnl.gov/tutorials/pthreads/#ConVarOverview,“调用 pthread_cond_signal() 后未能解锁互斥锁可能不允许匹配的 pthread_cond_wait() 例程完成(它将保持阻塞)。 " 我想那时,解锁,也许只是之后,是必需的。

0 投票
2 回答
6523 浏览

c - Windows 条件变量与事件

我们可以使用新的条件变量原语或 windows 事件来同步 WinNT v6.x 或更高版本中的线程。考虑以下两种方法,我们希望worker在main中设置“go”时同时运行,否则它们都应该阻塞。

或者

在第一种方法中,工作人员在SleepConditionVariableSRW上被阻止并被WakeAllConditionVariable唤醒。其次,它们在WaitForSingleObject上被阻塞并被SetEvent唤醒。

哪一个在实践中更好,仅关于开销?(提示:上下文切换锁竞争阻塞线程的开销

我会选择第一个,但觉得缺乏理由。

0 投票
3 回答
11382 浏览

algorithm - 如何使用信号量实现条件变量?

不久前,我在考虑如何相互实现各种同步原语。例如,在 pthread 中,您可以获得互斥锁和条件变量,并且可以从中构建信号量。

在 Windows API(或者至少是旧版本的 Windows API)中有互斥锁和信号量,但没有条件变量。我认为应该可以从互斥锁和信号量中构建条件变量,但对于我的生活,我就是想不出办法。

有谁知道这样做的好结构?

0 投票
5 回答
24997 浏览

c++ - 条件变量 - 为什么在调用 pthread_cond_wait() 之前调用 pthread_cond_signal() 是一个逻辑错误?

它是在 POSIX 线程教程 https://computing.llnl.gov/tutorials/pthreads/ 中写的,这是一个逻辑错误。

我的问题是为什么这是一个逻辑错误?

在我的程序中,我需要使用这些信号,但是我不能保证会有一个线程处于 _cond_wait 状态。我试图测试它,但没有任何反应。这会导致意外行为或更糟吗?

谢谢你!

0 投票
2 回答
847 浏览

c++ - 条件变量

我注意到,当我对条件变量执行等待操作时,它会立即返回。结果是,当执行以下虚拟代码时,一个 CPU 的 100% 正在循环中使用:

}

我希望调用cond.wait(lock)将线程置于不消耗任何 CPU 的状态,但事实并非如此。

那么问题出在哪里?我从 boost 文档中获取了上面的代码。

(我正在使用提升 1.44)

谢谢,

纪尧姆