C++多线程

您所在的位置:网站首页 c++线程互斥锁 C++多线程

C++多线程

2024-07-11 20:34| 来源: 网络整理| 查看: 265

0 引言

此篇为本专栏的第一篇文章。本专栏主要讲解C++并发编程相关的实践。包括但不限于

基于锁的数据结构无锁数据结构并发编程的一些注意事项线程池C++20与并发编程相关的新特性

首先,我们从基于锁的数据结构讲起。

前段时间,我某个同事面试字节某业务时,面试官让其实现一个线程安全的哈希表。本文便以此开始,分几篇来讲解基于锁的线程安全的一些数据结构

栈队列哈希表 1.  线程数据结构设计准则

并发数据的目的是要保证:

线程安全真正并发

为了达到这两个目的,在设计基于锁的线程安全的数据结构时需要考虑

需要保证数据结构的一致性(没有线程可以看到数据结构的不变量被破坏)防止数据接口本身接口间的race condition确保数据结构在异常发生时的安全性防止死锁尽量达到真正的并发 2. 基于锁的的哈希表设计

当面试官要求设计一个线程安全的哈希表时,可以参考如下思路

是不是采用锁的?需要有哪些接口?是不是可以使用std::map等stl库?

等等。

我们假设是基于锁的哈希表,首先考虑一下相应的接口,不能支持哪些接口?

不能支持operator[] 因为这个可能修改元素不支持iterator模式 2.1 基于std::map的哈希表

为了简化相应的实现,此线程安全的哈希表仅提供如下功能

增加一个新的key/value更新相应key的value移除一个key及其相应的value获得一个key及其相应的value template class ThreadSafeMap { private: std::shared_mutex mut_; std::map table_; public: ThreadSafeMap() = default; ThreadSafeMap(const ThreadSafeMap&) = delete; ThreadSafeMap& operator=(const ThreadSafeMap&) = delete; std::shared_ptr valueFor(const Key& key) { std::shared_lock lk(mut_); auto iter = table_.find(key); if (iter != table_.end()) return iter->second; return nullptr; } void addOrUpdate(const Key& key, const Value& value) { auto v = std::make_shared(value); std::unique_lock lk(mut_); auto iter = table_.find(key); if (iter != table_.end()) iter->second = std::move(v); table_.emplace(key, v); } void remove(const Key& key) { std::unique_lock lk(mut_); table_.erase(key); } };

上述代码测试用例如下

int main() { ThreadSafeMap mp; std::thread t1{[&mp]() { mp.addOrUpdate(10, "hello world"); mp.addOrUpdate(1, "hello"); }}; std::thread t2{[&mp]() { mp.addOrUpdate(11, "hello world"); std::this_thread::sleep_for(std::chrono::milliseconds{10}); auto value = mp.valueFor(1); if (value == nullptr) return; std::cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3