gpt4 book ai didi

c++ - 在这种情况下有什么正确的方法来实现锁定?

转载 作者:行者123 更新时间:2023-11-27 22:39:26 24 4
gpt4 key购买 nike

我有一个对象数组,我想在线程中对其进行操作,但我也希望有时能够访问。这感觉像是实现我的目标的一种 hacky 方法,但是有没有更好的方法来做这样的事情?:
*基本目标是拥有2把锁。一种允许所有单独的线程并发工作,同时阻止对数组的访问,直到它们全部完成,另一种允许关闭线程的访问以确保在函数运行时其他线程不会接触任何对象。

atomic<int> inThreadCount;
atomic<int> arrayLock;
map<string, MyObj*> myMap;
mutex mu1;
class MyObj{
mutex mu2;
int myInt;
public:
void update(bool shouldLowerCount){
mu2.lock();
myInt++;
if (shouldLowerCount)
inThreadCount--;
mu2.unlock();
}
}
//Some operation that requires all threads to finish first
//and doesn't allow threads to access the objects while running
void GetSnapshot(){
mu1.lock();
arrayLock++;
while (inThreadCount > 0)
Sleep(0);
map<string, MyObj *>::iterator it = myMap.begin();
auto t = time(nullptr);
auto tm = *localtime(&t);
cout << put_time(&tm, "%d-%m-%Y %H-%M-%S") << endl;
for( ; it != myMap.end(); ++it){
cout << it->first << ":" << it->second->counter);
}
arrayLock--;
mu1.unlock();
}

void updateObject(MyObj* myObj){
while (arrayLock > 0)
Sleep(0);
inThreadCount++;
async(std::launch::async, myObj->update(true));
}

PS,我意识到 Sleep() 和 arrayLock/inThreadCount++ 之间存在一个很小的错误机会窗口。这是我要解决的部分问题!

最佳答案

我认为您要求的是共享互斥体。共享互斥锁(或读写互斥锁)允许多个线程并行锁定一个对象,同时还允许一次一个线程独占锁定它。

简单来说,如果一个线程请求共享访问,它就会被授予,除非一个线程独占地持有该对象。当对象未被任何其他线程持有(共享或独占)时,线程被授予独占性。

它的常见用途是读写排他性。请参阅读取的共享访问权限和写入的独占访问权限。这是有效的,因为只有当两个或多个线程访问相同数据并且其中至少一个是写操作时,才会发生数据竞争。多个读者不是数据竞赛。

与独占锁相比,实现共享锁通常会产生开销,并且该模型通常只在有“很多”读者的情况下有用 “经常”读取和“不频繁”写入操作。 “很多”、“频繁”和“不频繁”的含义取决于平台和手头的问题。

这正是共享互斥锁的用途。C++17 支持开箱即用 std::shared_mutex但我注意到这个问题被标记为 C++11。

一些实现已经提供了一段时间(这是一种经典的锁定策略)或者你可以试试 boost::shared_mutex<> .

注意:共享锁的挑战之一是避免对写入器进行活锁。如果有很多读者经常阅读,那么作者很容易被无限期地“锁定”并且永远不会进步(或进步非常缓慢)。一个好的共享锁将为作者最终获得轮到提供一些保证。这可能是绝对优先级(不允许编写器在线程开始等待后启动

关于c++ - 在这种情况下有什么正确的方法来实现锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50326314/

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