gpt4 book ai didi

c++ - 一个简单的非锁定读取并发映射的算法?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:27 25 4
gpt4 key购买 nike

我正在尝试编写一个线程安全的映射,但从不在读取时锁定或阻塞。我的尝试是使用在写入时复制的只读映射。这个想法是 get() 是无锁的,而 put() 将当前只读的底层映射复制到一个新映射,执行 put,并换出新 map 的当前底层 map 。 (是的,put() 效率低下,因为它复制了整个 map ,但我不关心我的用例)

我第一次使用 std::atomic<*StringMap> 作为只读映射 但是 这有一个巨大的错误,可能是由于我的 java 背景。 get() 以原子方式获取指向底层映射的指针,加载时它可能是也可能不是当前映射(这没问题)。但是 put() 会在将底层 map 换成新 map 后将其删除。如果 get() 在旧 map 被删除时调用它,这显然会崩溃。

我的一个 friend 建议使用 shared_ptr,但他不确定 shared_ptr 操作是否在幕后进行任何锁定。 尽管文档说它是线程安全的。 编辑: 正如 nosid 指出的那样,它不是线程安全的,我需要来自 std::atomic 的特殊原子操作。

所以我的问题是:1. 这个算法可行吗? 2. shared_ptr 操作是否进行任何锁定,尤其是在访问时?

#include <unordered_map>
#include <atomic>
#include <pthread.h>
#include <memory>

typedef std::unordered_map<std::string, std::string> StringMap;

class NonBlockingReadMap {
private:
pthread_mutex_t fMutex;
std::shared_ptr<StringMap> fspReadMapReference;


public:

NonBlockingReadMap() {
fspReadMapReference = std::make_shared<StringMap>();
}

~NonBlockingReadMap() {
//so, nothing here?
}

std::string get(std::string &key) {
//does this access trigger any locking?
return fspReadMapReference->at(key);
}

void put(std::string &key, std::string &value) {
pthread_mutex_lock(&fMutex);
std::shared_ptr<StringMap> spMapCopy = std::make_shared<StringMap>(*fspReadMapReference);
std::pair<std::string, std::string> kvPair(key, value);
spMapCopy->insert(kvPair);
fspReadMapReference.swap(spMapCopy);
pthread_mutex_unlock(&fMutex);
}

void clear() {
pthread_mutex_lock(&fMutex);
std::shared_ptr<StringMap> spMapCopy = std::make_shared<StringMap>(*fspReadMapReference);
fspReadMapReference.swap(spMapCopy);
spMapCopy->clear();
pthread_mutex_unlock(&fMutex);
}

};

最佳答案

您的代码在 std::shared_ptr 上包含一个数据竞争,并且具有数据竞争 的程序的行为在 C++ 中未定义。

问题是:std::shared_ptr 类不是线程安全的。但是std::shared_ptr有特殊的原子操作,可以用来解决问题。

您可以在以下网页上找到有关这些原子操作的更多信息:

关于c++ - 一个简单的非锁定读取并发映射的算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24661079/

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