设为首页 加入收藏

TOP

1.1.3 一个线程安全的Counter 示例
2013-10-07 16:01:13 来源: 作者: 【 】 浏览:65
Tags:1.1.3 一个 线程 安全 Counter 示例

1.1.3 一个线程安全的Counter 示例

编写单个的线程安全的class 不算太难,只需用同步原语保护其内部状态。例如下面这个简单的计数器类Counter:

  1. 1 // A thread-safe counter  
  2. 2 class Counter : boost::noncopyable  
  3. 3 {  
  4. 4 // copy-ctor and assignment should be private by default for a class.  
  5. 5 public:  
  6. 6 Counter() : value_(0) {}  
  7. 7 int64_t value() const;  
  8. 8 int64_t getAndIncrease();  
  9. 9  
  10. 10 private:  
  11. 11 int64_t value_;  
  12. 12 mutable MutexLock mutex_;  
  13. 13 };  
  14. 14  
  15. 15 int64_t Counter::value() const  
  16. 16 {  
  17. 17 MutexLockGuard lock(mutex_); // lock 的析构会晚于返回对象的构造,  
  18. 18 return value_; // 因此有效地保护了这个共享数据。  
  19. 19 }  
  20. 20  
  21. 21 int64_t Counter::getAndIncrease()  
  22. 22 {  
  23. 23 MutexLockGuard lock(mutex_);  
  24. 24 int64_t ret = value_++;  
  25. 25 return ret;  
  26. 26 }  
  27. 27 // In a real world, atomic operations are preferred.  
  28. 28 // 当然在实际项目中,这个class 用原子操作更合理,这里用锁仅仅为了举例。 

这个class 很直白,一看就明白,也容易验证它是线程安全的。每个Counter 对象有自己的mutex_,因此不同对象之间不构成锁争用(lock contention)。即两个线程有可能同时执行L24,前提是它们访问的不是同一个Counter 对象。注意到其mutex_ 成员是mutable 的,意味着const 成员函数如Counter::value() 也能直接使用non-const 的mutex_。思考:如果mutex_ 是static,是否影响正确性和/或性能?

尽管这个Counter 本身毫无疑问是线程安全的,但如果Counter 是动态创建的并通过指针来访问,前面提到的对象销毁的race condition 仍然存在。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇1.1.2 MutexLock 与MutexLockGuard 下一篇1.2 对象的创建很简单

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·MySQL 安装及连接-腾 (2025-12-25 06:20:28)
·MySQL的下载、安装、 (2025-12-25 06:20:26)
·MySQL 中文网:探索 (2025-12-25 06:20:23)
·Shell脚本:Linux Sh (2025-12-25 05:50:11)
·VMware虚拟机安装Lin (2025-12-25 05:50:08)