gpt4 book ai didi

c++ - 线程锁定互斥量比 std::conditional_variable::wait() 更快

转载 作者:行者123 更新时间:2023-11-28 01:48:40 25 4
gpt4 key购买 nike

我正在尝试理解 condition_variables。

我想我的代码应该像这样工作:
1.主锁mx
2. main wait() notify <= here lock released
3.线程锁mx
4.线程发送通知
5.线程解锁mx
6. main wait()完成并锁定mx

那么为什么线程可以比 notify 后调用 wait() 更快地锁定 mx?
Example

#include <iostream>
#include <future>
#include <condition_variable>
#include <vector>

using namespace std::chrono_literals;

std::shared_future<void> ready;

std::mutex finish_mx;
std::condition_variable finish_cv;

int execute(int val, const std::shared_future<void> &ready){
ready.wait();

std::lock_guard<std::mutex> lock(finish_mx);
std::cout<<"Locked: "<<val<<std::endl;
finish_cv.notify_one();

return val;
}


int main()
{
std::promise<void> promise;
auto shared = promise.get_future().share();

std::vector<std::future<int>> pool;
for (int i=0; i<10; ++i){
auto fut = std::async(std::launch::async, execute, i, std::cref(shared));
pool.push_back(std::move(fut));
}

std::this_thread::sleep_for(100ms);

std::unique_lock<std::mutex> finish_lock(finish_mx);
promise.set_value();

for (int i=0; pool.size() > 0; ++i)
{
finish_cv.wait(finish_lock);
std::cout<<"Notifies: "<<i<<std::endl;

for (auto it = pool.begin(); it != pool.end(); ++it) {
auto state = it->wait_for(0ms);
if (state == std::future_status::ready) {
pool.erase(it);
break;
}
}
}
}

示例输出:

Locked: 6
Locked: 7
Locked: 8
Locked: 9
Locked: 5
Locked: 4
Locked: 3
Locked: 2
Locked: 1
Notifies: 0
Locked: 0
Notifies: 1

编辑

for (int i=0; pool.size() > 0; ++i)
{
finish_cv.wait(finish_lock);
std::cout<<"Notifies: "<<i<<std::endl;

auto it = pool.begin();
while (it != pool.end()) {
auto state = it->wait_for(0ms);
if (state == std::future_status::ready) {
/* process result */
it = pool.erase(it);
} else {
++it;
}
}
}

最佳答案

这取决于您的操作系统如何安排等待获取互斥锁的线程。在第一个 notify_one 之前,所有 execute 线程都已经在等待获取互斥锁,因此如果有一个简单的 FIFO 线程队列等待锁定互斥锁,那么它们都领先队列中的 main 线程。随着每个互斥体解锁互斥体,队列中的下一个互斥体将锁定它。

这与互斥量比条件变量“更快”无关,条件变量必须锁定相同的互斥量才能从等待中返回。

一旦 future 准备就绪,所有 execute 线程都会从 wait 返回并尝试锁定互斥量,加入等待者队列。当条件变量开始等待时,互斥锁被解锁,其他线程之一(队列前面的线程)获得锁。它调用 notify_one 导致条件变量尝试重新锁定互斥锁,加入队列的后面。通知线程解锁互斥量,队列中的下一个线程获得锁,并调用 notify_one(它什么都不做,因为条件变量已经被通知并等待锁定互斥量)。然后队列中的下一个线程获得互斥锁,依此类推。

似乎其中一个 execute 线程运行速度不够快,无法在第一个 notify_one 调用之前进入队列,因此它最终排在后面的队列中条件变量。

关于c++ - 线程锁定互斥量比 std::conditional_variable::wait() 更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43859143/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com