可以使用原子来减少在读取的主导多线程程序中的锁定吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可以使用原子来减少在读取的主导多线程程序中的锁定吗?相关的知识,希望对你有一定的参考价值。
最近,我发现自己经常处于共享数据被读取很多但很少被写入的情况,所以我开始怀疑是否可以稍微加快同步速度。
以下面的示例为例,其中多个线程偶尔写入数据,单个线程经常读取数据,所有线程都与普通互斥锁同步。
#include <iostream>
#include <unistd.h>
#include <unordered_map>
#include <mutex>
#include <thread>
using namespace std;
unordered_map<int, int> someData({{1,10}});
mutex mu;
void writeData(){
while(true){
{
lock_guard<mutex> lock(mu);
int r = rand()%10;
someData[1] = r;
printf("data changed to %d
", r);
}
usleep(rand()%100000000 + 100000000);
}
}
void readData(){
while(true){
{
lock_guard<mutex> lock(mu);
for(auto &i:someData){
printf("%d:%d
", i.first, i.second);
}
}
usleep(100);
}
}
int main() {
thread writeT1(&writeData2);
thread writeT2(&writeData2);
thread readT(&readData2);
readT.join();
}
使用普通的锁定机制,每次读取都需要一个锁定,我正在考虑加快单个原子读取的速度。[[在大多数情况下]:]]unordered_map<int, int> someData({{1,10}});
mutex mu;
atomic_int dataVersion{0};
void writeData2(){
while(true){
{
lock_guard<mutex> lock(mu);
dataVersion.fetch_add(1, memory_order_acquire);
int r = rand()%10;
someData[1] = r;
printf("data changed to %d
", r);
}
usleep(rand()%100000000 + 100000000);
}
}
void readData2(){
mu.lock();
int versionCopy = dataVersion.load();
auto dataCopy = someData;
mu.unlock();
while(true){
if (versionCopy != dataVersion.load(memory_order_relaxed)){
lock_guard<mutex> lock(mu);
versionCopy = dataVersion.load(memory_order_relaxed);
dataCopy = someData;
}
else{
for(auto &i:dataCopy){
printf("%d:%d
", i.first, i.second);
}
usleep(100);
}
}
}
这里的数据类型unordered_map
只是一个例子,它可以是任何类型,并且我不是在寻找纯粹的无锁算法,因为这可能是另外一回事了。仅对于基于普通锁的同步,在大多数操作被读取的情况下,使用这样的技巧,从逻辑上讲可以吗?有没有确定的方法?
[编辑]
- 我知道
- 共享的互斥锁
最近,我发现自己经常处于共享数据被读取很多而却很少被写入的情况,因此我开始怀疑是否可以稍微加快同步速度。将以下内容作为...
[在大多数(每个?)操作系统中,在没有争议的情况下,锁定原语本身是由原子处理的;仅在竞争时恢复到内核。考虑到这一点,最好在保持锁的同时尽量减少代码量,因此第一个循环应为:
int r = rand()%10;
mu.lock();
someData[1] = r;
mu.unlock();
printf("data changed to %d
", r);
我不知道您将如何解决读取方面的问题,但是如果您选择一个友好的数据存储,则可以用相同的方式将对它的访问减至最少。实现,它们通常使用一些便宜而乐观的(原子/自旋锁)机制,几乎没有-在没有碰撞的情况下不会产生影响(大多数时候没有作者)。您似乎并不在乎您的副本有多大/最近。对于某些信息性能计数器来说,这是可以接受的,但我会三思而后行-并非其他人必须维护您的代码,这是期望或什至不会想到的事情。其后果可能是灾难性的。
- 频繁读取,偶尔写入。
以上是关于可以使用原子来减少在读取的主导多线程程序中的锁定吗?的主要内容,如果未能解决你的问题,请参考以下文章