muduo网络库学习之BlockinngQueue<T>类、ThreadPool 类、Singleton类封装中的知识点

一、BlockinngQueue<T>类、BoundedBlockingQueue<T>类

生产者消费者问题,可以用信号量+互斥锁 或者 条件变量+互斥锁 来解决,还分为有界和无界缓冲区两种情形,如下图:

有界缓冲区:

生产者:

信号量+互斥锁:1,2,3,4,5

条件变量+互斥锁:2,1,3,5,4(外框)

消费者:

信号量+互斥锁:1,2,3,4,5

条件变量+互斥锁:2,1,3,5,4(外框)

无界缓冲区:

生产者:

信号量+互斥锁:2,3,4,5

条件变量+互斥锁:2,3,5,4(外框)

消费者:

信号量+互斥锁:1,2,3,4

条件变量+互斥锁:2,1,3,4(外框)

template<typename T> class BlockingQueue : boost::noncopyable

无界缓冲区:使用条件变量+互斥锁实现,put()可以看作是生产者,take()可以看作实现消费者,内部的实现就是上述4个步骤的集合。

template<typename T> class BoundedBlockingQueue : boost::noncopyable

有界缓冲区:与无界缓冲区多了一个条件变量notFull成员,并且使用boost库的环形缓冲区。

二、ThreadPool类(固定线程数,不考虑线程数动态增减)

线程池本质上也是生产者消费者问题:

生产者线程向任务队列添加任务,消费者线程(在线程队列中)从任务队列取出任务去执行。

class ThreadPool : boost::noncopyable

typedef boost::function<void ()> Task;

代码中有这么一段:

threads_.push_back(new muduo::Thread(
                       boost::bind(&ThreadPool::runInThread, this), name_ + id));
threads_[i].start();

初看有点奇怪,其实是因为ptr_vector<T>重载了[], 即 T& operator[]( size_type n );

三、singleton类

template<typename T> class Singleton : boost::noncopyable

1、pthread_once

pthread_once(&ponce_, &Singleton::init);

保证init函数只被调用一次,即只初始化一个对象。在init内部 value_ = new T();

2、atexit

  ::atexit(destroy);

在init 函数内注册destroy,在程序结束时会调用destroy,在destroy内部delete value_;

3、typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];

假设class A; A* p; delete p; 现在A只是前向声明,是不完全类型,那么delete p会出问题,但在编译时只是报警告。

sizeof(A) == 0; 故 typedef char T_must[-1]; 在编译时就会出错。

参考:

muduo manual.pdf

《linux 多线程服务器编程:使用muduo c++网络库》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏余林丰

13.ThreadPoolExecutor线程池之submit方法

jdk1.7.0_79   在上一篇《ThreadPoolExecutor线程池原理及其execute方法》中提到了线程池ThreadPoolExecutor...

20410
来自专栏Java帮帮-微信公众号-技术文章全总结

第二十五天 多线程-常用方法&线程池【悟空教程】

System.out.println(getName() + " ==== " + i );

1063
来自专栏Java帮帮-微信公众号-技术文章全总结

Java多线程详解2

Java多线程详解 Java线程:线程的同步与锁 一、同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。 例如:两个线程Threa...

3307
来自专栏青枫的专栏

调用Thread类的方法:public final String getName() 为什么得到的线程对象的名称默认是:Thread-0、Thread-1、Thread-2、...呢?

调用Thread类的方法:public final String getName() 为什么得到的线程对象的名称默认是:Thread-0、Thread-1、Th...

452
来自专栏Android 研究

Android Handler机制12之Callable、Future和FutureTask

说到Callable就不能不说下java.lang.Runnable,它是一个接口,它只声明了一个run()方法,由于这个run()方法的返回值是void的,所...

922
来自专栏Java 源码分析

Java多线程JUC

1. volatile 关键字 多线程访问的时候,一个比较严重的问题就是内存不可见,其实在内存访问的时候每一个线程都有一个自己的缓冲区,每次在做修改的时候都是从...

2643
来自专栏栗霖积跬步之旅

1.7停止线程

线程停止:在线程处理完任务之前,停掉正在做的操作,也就是放弃当前操作。 在java中有三种方法可以实现线程的停止: 使用退出标志,使线程正常退出,也就是当run...

1770
来自专栏小勇DW3

LockSupport的源码实现原理以及应用

如果只是LockSupport在使用起来比Object的wait/notify简单,

1152
来自专栏java工会

Java多线程实现的三种方式

1505
来自专栏小怪聊职场

Java中实现多线程的3种方法介绍和比较

2549

扫码关注云+社区