问题标签 [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 回答
229 浏览

io - 等待互斥体、条件变量或 I/O 是否会自动 yield() 线程?

这似乎很容易,但只是想检查这是否得到保证(在 Linux 上)。在满足等待条件之前,线程是否被排除在调度之外?或者线程会被调度,发现它仍在等待并再次 yield(),浪费资源?

我要问的原因是,如果我有 X 个线程正在运行,并且某些线程由于某种原因被阻塞,被阻塞的线程是否会妨碍可运行线程(假设它们具有相同的优先级)?

0 投票
1 回答
1202 浏览

c++ - C++11 线程:notify_all() 或 notify_one() 当我只有一个时?

我的线程作为链表运行(有重叠,因此有线程),实现了与时间线没有什么不同的东西。每个条件变量解锁链表中的下一个线程。

我应该使用notify_all()还是notify_one()当我只有一个要通知时?

0 投票
1 回答
436 浏览

windows - 如何让调试器强制 Windows 线程从睡眠中唤醒?

我正在调试一个死锁。我想唤醒一个正在等待条件变量的线程,以便在它重新检查睡眠条件时进行跟踪。在条件变量上睡觉会受到虚假唤醒的影响,那么我该如何强制这样的唤醒呢?

0 投票
2 回答
1170 浏览

c# - C# 中的 Monitor.Pulse 出现次优:必须在锁定范围内

剧透注:问题是最后一句话。

在 C# 中,使用条件变量的经典模式是这样的:

和其他一些线程:

这是我的代码中的一个例子。如果我将 Pulse 放在锁定范围之外,它不会编译。但是,这是正确的方法:cf:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686903(v=vs.85).aspx 和: http: //www.installsetupconfig.com/win32programming/threadprocesssynchronizationapis11_7.html (搜索“里面”)

实际上,当您仍处于关键部分时,向睡眠线程发出信号是愚蠢的。因为睡眠线程不能唤醒(不是立即),因为它也在一个关键部分中!

因此,我希望 .NET 或 C# Pulse 调用实际上只是标记锁定对象,以便当它超出范围时,此时它实际上“脉冲”条件变量。因为否则,它将有一个最优性问题。

那么,Monitor 对象的设计是如何选择的呢?

编辑:

我在这篇论文中找到了答案: http ://research.microsoft.com/pubs/64242/implementingcvs.pdf 部分“优化信号和广播”以及上一节关于 NT 内核以及如何在信号量之上制作条件变量,这就是引入“该死的队列”的原因。现在,这让我成为了一名更好的工程师。

0 投票
1 回答
872 浏览

c++ - 如何在生产者-消费者场景中使用 Boost 条件变量?

编辑:下面

我有一个线程负责从缓冲区中的设备流式传输数据。此外,我有 N 个线程对该数据进行一些处理。在我的设置中,我希望流媒体线程从设备中获取数据,并等待 N 个线程完成处理,然后再获取新数据或达到超时。N 个线程应该等到新数据被提取后再继续处理。我相信如果我不希望 N 个线程在缓冲区上重复处理并且如果我希望处理所有缓冲区而不跳过任何缓冲区,那么这个框架应该可以工作。

仔细阅读后,我发现条件变量正是我所需要的。我遵循了教程和其他堆栈溢出问题,这就是我所拥有的:

全局变量:

成员变量:

数据接收器循环(1个线程运行):

数据处理循环(N个线程运行这个)

这两个循环在它们自己的同一个类的成员函数中。变量buffer是成员变量,所以可以跨线程共享。

接收者线程将首先启动。data_ready 变量是一个大小为 N 的 bool 向量。如果数据已准备好处理,则 data_ready[i] 为真,如果线程已处理数据,则为假。如果 data_ready 的任何元素为真,则函数 any(data_ready) 输出真,否则输出假。set_true(data_ready) 函数将 data_ready 的所有元素设置为 true。接收线程将检查是否有任何处理线程仍在处理。如果没有,它将获取数据,设置 data_ready 标志,通知线程,并继续循环,该循环将在开始处停止,直到处理完成。处理线程将检查它们各自的 data_ready 标志是否为真。一旦为真,处理线程将进行一些计算,将其各自的 data_ready 标志设置为 0,然后继续循环。

如果我只有一个处理线程,程序运行良好。一旦我添加了更多线程,我就会遇到处理输出是垃圾的问题。此外,由于某种原因,处理线程的顺序很重要;换句话说,我启动的最后一个线程将输出正确的数据,而之前的线程将输出垃圾,无论处理的输入参数是什么(假设有效参数)。我不知道问题是由于我的线程代码还是我的设备或数据处理设置有问题。我尝试在处理和接收步骤中使用 couts,并且使用 N 个处理线程,我看到了应该的输出:

条件变量的使用是否正确?可能是什么问题呢?

编辑:我遵循了 fork 的建议并将代码更改为:

数据接收器循环(1个线程运行):

数据处理循环(N个线程运行这个)

它工作得更好一些。我使用了正确的锁吗?

0 投票
1 回答
1119 浏览

c++ - Reader-writer lock with condition variable

I find neither boost nor tbb library's condition variable has the interface of working with reader-writer lock (ie. shared mutex in boost). condition_variable::wait() only accepts mutex lock. But I think it's quite reasonable to have it work with reader-writer lock. Can anyone tell me the reason why they don't support that, or why people don't do that?

Thanks, Cui

0 投票
4 回答
6489 浏览

c++ - std::condition_variable 虚假阻塞

如您所知,应循环调用条件变量以避免虚假唤醒。像这样:

如果另一个线程想要唤醒等待线程,它必须将条件标志设置为真。例如:

我想知道,这种情况是否有可能阻止条件变量:

1)等待线程检查条件标志,发现它等于FALSE,所以,它要进入condvar.wait()例程。

2)但就在此之前(但在条件标志检查之后)等待线程被内核抢占(例如,由于时隙到期)。

3)此时,另一个线程想要通知等待线程条件。它将条件标志设置为 TRUE 并调用condvar.notify_one();

4)当内核调度器再次运行第一个线程时,它进入condvar.wait()例程,但已经错过了通知。

因此,尽管条件标志设置为 TRUE,但等待线程无法退出condvar.wait(),因为不再有唤醒通知。

是否可以?

0 投票
2 回答
1772 浏览

c++ - std::condition_variable::notify_one() 调用了两次

如果我在没有任何时间间隔的情况下两次调用 std::condition_variable::notify_one() 会唤醒多少个等待线程,如下所示:

是否可以保证这些通知将被传递到不同的线程,而不是多次传递给同一个线程?

0 投票
1 回答
1855 浏览

c++ - 多次调用 std::condition_variable::notify_one() 而没有上下文切换

在此示例中将唤醒多少个等待线程:

第一个线程

第二个线程

第三个线程(与第二个相同):

是否可以保证在此示例中两个通知都将传递到不同的线程,而不是多次传递给同一个线程?

即 notify_one() 是什么意思:

(*) 注意!我不是在这里谈论场景“等待线程已经在过去的某个地方得到通知,被唤醒,做一些事情并再次进入 condvar.wait()” - 当然,在这种情况下,可以唤醒几个 notify_one() 例程同样的线程一遍又一遍。

我说的是另一个案例

notify_one() 已通知等待线程唤醒,但在此等待线程从内核调度程序接收到时隙并继续执行之前 - 另一个 notify_one() 已被再次调用。是否有可能第二个通知将再次传递到同一个线程,而它还没有从第一个通知中唤醒?

0 投票
8 回答
144076 浏览

c++ - C++11 线程安全队列

我正在处理的一个项目使用多个线程来处理一组文件。每个线程都可以将文件添加到要处理的文件列表中,因此我将(我认为是)一个线程安全队列放在一起。相关部分如下:

但是,我偶尔会在if (...wait_for(lock, timeout) == std::cv_status::no_timeout) { }块内发生段错误,并且 gdb 中的检查表明由于队列为空而正在发生段错误。这怎么可能?据我了解,wait_for只有在收到通知时才会返回cv_status::no_timeout,并且这应该只在FileQueue::enqueue刚刚将新项目推送到队列后才会发生。