C++多线程 |
您所在的位置:网站首页 › c++线程互斥锁 › C++多线程 |
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 |