私はcondition_variablesを理解しようとしています。スレッドはmutexをstd :: conditional_variable :: wait()より速くロックします
私は私のコードは次のように動作する必要がありますね:
3.スレッドが
4.スレッドが
5に通知送信MXをロックするロック解除ここ< =通知)
1.メインロックMX
2.メイン待ち時間(スレッドのロック解除mx
メインwait()が終了してロックmx
なぜスレッドは通知後に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()の後に結果を得る最良の方法は、すべての未来をチェックすることです。 – Alex
あなたが何を求めているのか分かりません。申し訳ありません。 'notify_one'呼び出しと条件変数の起動との間に1対1の対応が必要な場合は、複数の条件変数または異なる形式の同期を使用する必要があります。 –