muduo网络库源码学习————条件变量
来源:互联网 发布:反转故事知乎 编辑:程序博客网 时间:2024/05/22 20:28
muduo里的CountDownLatch类实际上是对条件变量condition进行的封装,既可以用于所有子线程等待主线程发起 “起跑” ,也可以用于主线程等待子线程初始化完毕才开始工作。
condition.h代码如下:
// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)//条件变量#ifndef MUDUO_BASE_CONDITION_H#define MUDUO_BASE_CONDITION_H#include <muduo/base/Mutex.h>#include <boost/noncopyable.hpp>#include <pthread.h>namespace muduo{class Condition : boost::noncopyable{ public: //构造函数只能显式调用 explicit Condition(MutexLock& mutex) : mutex_(mutex) {//构造函数初始化条件变量 pthread_cond_init(&pcond_, NULL); } //析构函数 ~Condition() {//析构函数销毁条件变量 pthread_cond_destroy(&pcond_); } //等待函数 void wait() { pthread_cond_wait(&pcond_, mutex_.getPthreadMutex()); } // returns true if time out, false otherwise. bool waitForSeconds(int seconds); //signal函数 void notify() { pthread_cond_signal(&pcond_); } //broadcast函数 void notifyAll() { pthread_cond_broadcast(&pcond_); } private: MutexLock& mutex_;//锁,不拥有他,是一个引用,不负责管理他的生存期 pthread_cond_t pcond_;//为一个条件变量};}#endif // MUDUO_BASE_CONDITION_H
condition.cc
// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)#include <muduo/base/Condition.h>#include <errno.h>// returns true if time out, false otherwise.bool muduo::Condition::waitForSeconds(int seconds){ struct timespec abstime; clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += seconds; return ETIMEDOUT == pthread_cond_timedwait(&pcond_, mutex_.getPthreadMutex(), &abstime);}
CountDownLatch.h
// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)//对条件变量的封装,既可以用于所有子线程等待主线程发起起跑命令,//也可以用于主线程等待子线程初始化完毕才开始工作#ifndef MUDUO_BASE_COUNTDOWNLATCH_H#define MUDUO_BASE_COUNTDOWNLATCH_H#include <muduo/base/Condition.h>#include <muduo/base/Mutex.h>#include <boost/noncopyable.hpp>namespace muduo{class CountDownLatch : boost::noncopyable{ public://构造函数,显示调用 explicit CountDownLatch(int count);//等待函数 void wait();//计数器减 void countDown();//获取当前计数器的值 int getCount() const; private://mutable表明在const里可以改变他的状态 mutable MutexLock mutex_;//互斥锁 Condition condition_;//条件变量 int count_;//计数器};}#endif // MUDUO_BASE_COUNTDOWNLATCH_H
CountDownLatch.cc
// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)#include <muduo/base/CountDownLatch.h>using namespace muduo;//构造函数对值进行初始化,参数为计数器,构造mutex_对象,将mutex_对象传到condition_里面CountDownLatch::CountDownLatch(int count): mutex_(), condition_(mutex_),count_(count){}void CountDownLatch::wait(){ MutexLockGuard lock(mutex_); //count_不为0则一直等待 while (count_ > 0) { condition_.wait(); }}void CountDownLatch::countDown(){ MutexLockGuard lock(mutex_); --count_;//count_减少 if (count_ == 0) {//如果count_为0,则通知所有的等待线程 condition_.notifyAll(); }}int CountDownLatch::getCount() const{//得到count_的值 MutexLockGuard lock(mutex_); return count_;}
测试代码需要自己编写,如下所示,该程序先打印主进程id,建立3个线程,wait等待主线程发号施令,然后睡眠3秒,之后发起号令,打印各个线程的id,代码如下:
#include <muduo/base/CountDownLatch.h>#include <muduo/base/Thread.h>#include <boost/bind.hpp>#include <boost/ptr_container/ptr_vector.hpp>#include <string>#include <stdio.h>//测试程序using namespace muduo;class Test{ public: Test(int numThreads) : latch_(1),threads_(numThreads) {//CountDownLatch对象的计数值初始化为1,线程对象数组的容量初始化为传进来的参数 for (int i = 0; i < numThreads; ++i) {//创建numThreads个线程 char name[32];//线程的名称 snprintf(name, sizeof name, "work thread %d", i); //创建线程,threadFunc为回调函数,因为是成员函数,所以要用&,this为当前类指针 threads_.push_back(new muduo::Thread(boost::bind(&Test::threadFunc, this), muduo::string(name))); } //占位符为参数 for_each(threads_.begin(), threads_.end(), boost::bind(&Thread::start, _1)); } void run() {//count_初始化的时候赋为1,这里只需执行一次既可以跳出等待 latch_.countDown(); } void joinAll() { for_each(threads_.begin(), threads_.end(), boost::bind(&Thread::join, _1)); } private: void threadFunc() { latch_.wait();//等待主线程发号施令 printf("tid=%d, %s started\n", CurrentThread::tid(), CurrentThread::name()); printf("tid=%d, %s stopped\n",CurrentThread::tid(),CurrentThread::name()); } CountDownLatch latch_;//CountDownLatch对象 boost::ptr_vector<Thread> threads_;//线程对象数组};int main(){//首先打印当前进程pid,当前线程tid printf("pid=%d, tid=%d\n", ::getpid(), CurrentThread::tid()); //构造Test对象 Test t(3); sleep(3); printf("pid=%d, tid=%d %s running ...\n", ::getpid(), CurrentThread::tid(), CurrentThread::name()); t.run();//发号施令 t.joinAll(); printf("number of created threads %d\n", Thread::numCreated());}
由于线程竞争,运行结果不唯一:
另一个结果:
0 0
- muduo网络库源码学习————条件变量
- muduo网络库源码学习————互斥锁
- muduo源码学习(6)-锁,条件变量
- muduo网络库学习笔记(4):互斥量和条件变量
- muduo网络库源码学习————Timestamp.cc
- muduo网络库源码学习————原子性操作Atomic.h
- muduo网络库源码学习————Exception类
- muduo网络库源码学习————线程类
- muduo网络库源码学习————无界队列和有界队列
- muduo网络库源码学习————线程池实现
- muduo网络库源码学习————线程安全
- muduo网络库源码学习————线程特定数据
- muduo网络库源码学习————线程本地单例类封装
- muduo网络库源码学习————日志类封装
- muduo网络库源码学习————日志滚动
- muduo库阅读(4)——基本类型之条件变量
- [Muduo网络库源码分析] (2) base/Condition.cc_h_条件变量操作
- Muduo库源码分析(5):互斥锁,条件变量类
- [leetcode]Valid Anagram C语言
- 【模板】【最小树形图】
- delpi2007 in x64 os(win7/8), 经常出现bordbk105N.dll错误
- pg数据库配置无需交互式输入密码连接服务端
- Storyboard中 UIViewController+UITableView使用 autolayout引起的界面布局问题
- muduo网络库源码学习————条件变量
- linux驱动之内存分配kmalloc
- Linux 命令
- iOS开发者申请发布证书及真机调试 图文详解
- VS中C++对象的内存布局
- UDT 分析
- NAT在NDIS中间层驱动中的实现
- 分治:棋盘覆盖的java程序实现
- 关于排序的稳定性与不稳定性