我正在测试边缘情况,std::condition_variable并测试了使一个线程挨饿的场景。场景是有 99 个生产者和只有 1 个消费者,所有这些生产者都在 1 个最大大小的队列上工作。notify_one(达到队列最大大小后)命中消费者的概率接近 1%。因此,这意味着它将命中另一个生产者,该生产者将检查谓词,然后等待互斥体。
我预计程序会在此时挂起,但我看到的是程序尝试了尽可能多的谓词,直到最终到达消费者。如果没有消费者,则永远在所有等待线程中检查谓词。
我的问题是:标准是否定义了notify_one()将尝试通知第一个具有正谓词结果的等待线程?那么为什么它可以在没有预测的情况下与消费者一起工作(注释代码)。或者这是一个虚假的唤醒,它正在努力唤醒我的等待线程?或者是其他东西?
在 Windows 上使用 Clang 和 MSVC 进行了测试。
我的代码重现该案例:
#include <condition_variable>
#include <mutex>
#include <queue>
#include <vector>
#include <iostream>
class CVSimple
{
public:
static void test() {
std::queue<int> que;
std::mutex m;
std::condition_variable cv;
int max_size = 10;
bool working = true;
auto producer = [&]() {
while (working) {
std::unique_lock<std::mutex> lock(m);
std::chrono::milliseconds t(200);
auto predicate = [&que, &max_size]() {
if (que.size() < max_size) {
std::cout << "T";
return true; …Run Code Online (Sandbox Code Playgroud) https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
// Inside of our lock, spawn a new thread, and then wait for it to start.
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap(); // #1
*started = true;
// We notify the condvar that the value has changed.
cvar.notify_one();
});
// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap(); // …Run Code Online (Sandbox Code Playgroud) 假设有两个线程,其中一个线程具有更高的优先级,并且它们在同一核心(单核)上运行,我只想同时只工作一个线程。(也许你说这不是线程范例,但实际上我只是做了我的这里问题最小)
T1 ~~~e1~e2~e3~e4~...~~~~~~~eK~~~~~~~~...~~~ eN~~~~~ ///(e1...eN)packed as a task.
| |
T2 ~~~~~~~~~~~~pause~~~~~~continue~~~~~~~~~~~~~~~~~~ ///(pause & continue)is just title time for T1 that T2 is operating (T2 has more priority).
Run Code Online (Sandbox Code Playgroud)
**~**是 time ,并且**e**是在那里求值的表达式。整个 e1、e2、... 是一个函数,即 api 调用函数(任务),所以我只想在那里暂停 T1(~pause~)并运行我的 T2 直到完成,完成后继续 T1。
注意:我无法更换
**e**工作(职能)。
我知道的?
创建条件变量(CV)并在完成时T2通知CV唤醒,但这不是我的成就,因为我想让T1立即在e4 (暂停时间)中精确暂停并继续T2直到完成(或我的继续时间)。
我的知识与: https: //en.cppreference.com/w/cpp/thread/condition_variable#Example 我们是否有立即暂停的 thread::方法(强制上下文切换)?(我不是说屈服!)