【发布时间】:2020-10-03 19:28:43
【问题描述】:
我试图很好地理解线程安全,所以,我有一个简单的代码(代码不是真实的),我已经应用了线程安全,如下所示:
vector<int> myList;
const unsigned short ListSize = 5;
mutex mut;
condition_variable cond;
void AddItem() {
for (int i = 0; i < ListSize + 2; i++) {
mut.lock();
myList.push_back(i);
mut.unlock();
cond.notify_one();
cout << "An item added." << "\n";
this_thread::sleep_for(chrono::milliseconds(300));
}
}
void RemoveItem() {
for (int i = 0; i < ListSize; i++) {
unique_lock<mutex> locker(mut);
cond.wait(locker, []() { return !myList.empty(); });
myList.erase(myList.begin());
cout << "An item removed." << "\n";
this_thread::sleep_for(chrono::milliseconds(300));
}
}
int main() {
thread th_task1(&AddItem);
thread th_task2(&RemoveItem);
th_task1.join();
th_task2.join();
if (!myList.empty()) {
cout << "There are " << myList.size() << " items." << "\n";
} else {
cout << "The list is empty." << "\n";
}
return 0;
}
另外,您可以测试来自here 的代码。
该代码是否被认为是线程安全的?如果不是如何使其成为线程安全的?
【问题讨论】:
-
随机想法。 cout 上有一个额外的锁争用可能会影响性能。循环可能运行时间太短而无法显示问题。抱着锁睡觉模拟大工作,这是你要测试的吗?创建线程的时间并非无关紧要,您可能希望从 mut 锁定开始并在创建两个线程后解锁它。谁可以使用互斥锁是否公平?
-
@Surt:谢谢你的想法。关于使用
std::cout和 sleep 它们只是为了测试。 (1)以锁定mut启动功能并在功能结束时解锁它是一种好方法,还是我必须锁定/解锁只是添加/删除项目的部分? (2) 当使用输入/输出流(std::cin,std::cout)时,是否也需要使用锁定/解锁?
标签: c++ multithreading thread-safety