我有以下代碼
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <set>
#include <string>
#include <chrono>
#include <atomic>
using namespace std;
set<string> messages_;
mutex mu;
void thread1() {
for(int i=0; i<20; i) {
{
lock_guard<mutex> lock(mu);
messages_.insert(to_string(i));
}
this_thread::sleep_for(chrono::milliseconds(20));
}
}
condition_variable cond;
mutex mutex_;
atomic<bool> stop{false};
int workaround = 0;
mutex* GetCoutMutex() {
static std::mutex mu;
return μ
}
void Work() {
workaround ;
unique_lock<mutex> lock(mu);
for(auto it=messages_.begin(); it!=messages_.end(); ) {
lock.unlock();
{
lock_guard<mutex> cout_lock(*GetCoutMutex());
cout << "work around: " << workaround << ", message: " << *it << endl;
}
lock.lock();
it=messages_.erase(it);
}
}
void thread2() {
while(!stop.load(memory_order_acquire)) {
Work();
unique_lock<mutex> lock(mutex_);
cond.wait_for(lock, chrono::milliseconds(50), []{ return stop.load(memory_order_acquire); });
}
}
int main() {
thread t1(thread1), t2(thread2);
t1.join();
this_thread::sleep_for(chrono::milliseconds(100));
stop.store(true, memory_order_release);
cond.notify_one();
t2.join();
}
我的預期輸出是
work around: 1, message: 0
work around: 2, message: 1
work around: 2, message: 2
work around: 3, message: 3
work around: 3, message: 4
work around: 4, message: 5
work around: 4, message: 6
work around: 4, message: 7
work around: 5, message: 8
work around: 5, message: 9
work around: 6, message: 10
work around: 6, message: 11
work around: 7, message: 12
work around: 7, message: 13
work around: 7, message: 14
work around: 8, message: 15
work around: 8, message: 16
work around: 9, message: 17
work around: 9, message: 18
work around: 9, message: 19
其中,訊息編號是遞增序列 0,1,2,...,19,大多數執行符合預期。但是,我在某些執行中得到了以下輸出:
work around: 1, message: 0
work around: 2, message: 1
work around: 2, message: 2
work around: 3, message: 3
work around: 3, message: 4
work around: 4, message: 5
work around: 4, message: 6
work around: 5, message: 7
work around: 5, message: 8
work around: 6, message: 10
work around: 6, message: 11
work around: 6, message: 9
work around: 7, message: 12
work around: 7, message: 13
work around: 8, message: 14
work around: 8, message: 15
work around: 9, message: 16
work around: 9, message: 17
work around: 9, message: 18
work around: 10, message: 19
據我所知,thread1和thread2是同步的mu
,所以thread1的插入應該對thread2可見。由于thread1在10之前插入9,并且thread2正在按順序迭代集合,所以9應該首先由thread2輸出。
我很困惑。有人可以解釋為什么 10 在 9 之前輸出嗎?
uj5u.com熱心網友回復:
由于集合包含std::string
,因此元素按字典順序排序。
假設執行緒 1 在執行緒 2 等待 condvar 時插入字串“9”、“10”和“11”。在這種情況下,“10”將是最小的字串,因此它將首先列印,然后是“11”和“9”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/470091.html