Linux组件封装(五) WorkShop的封装

我们封装好了Buffer后,却不知道具体要多少个线程,一个一个线程的去关联Buffer太繁琐了。

那么,我们是不是可以讲Buffer与线程的一个队列封装在一起呢 ?

由于vector中不能存放Thread,所以,我们应在vector中添加相应的Thread *,这样,就可以完成封装了。

声明代码如下:

 1 #ifndef WORKSHOP_H
 2 #define WORKSHOP_H
 3 #include "NonCopyable.h"
 4 #include "Buffer.h"
 5 #include <vector>
 6 class Producer;
 7 class Consumer;
 8 class WorkShop : NonCopyable
 9 {
10 public:
11     WorkShop(size_t bufferSize, size_t producerSize, size_t consumerSize);
12
13     ~WorkShop();
14     void startWork();
15 private:
16
17     size_t _bufferSize;
18
19     Buffer _buffer;
20     size_t _producerSize;
21     size_t _consumerSize;
22
23     std::vector<Producer *> _producers;
24     std::vector<Consumer *> _consumers;
25 };
26
27
28 #endif  /*WORKSHOP_H*/

接下来,我们需要实现声明中的函数,构造函数中,我们需要将两个vector中的指针初始化,将该vector的大小初始化为我们得到的vector大小,将每个指针初始化为NULL, 接下来,我们需要为每个指针new一个Thread对象,这样,就完成了初始化。

同样的,当我们析构的时候,也应该将vector中的指针delete掉。

cpp代码如下:

 1 #include "WorkShop.h"
 2 #include "Producer.h"
 3 #include "Consumer.h"
 4
 5 WorkShop::WorkShop(size_t bufferSize, size_t producerSize, size_t consumerSize)
 6     :_bufferSize(bufferSize),
 7      _buffer(_bufferSize),
 8      _producerSize(producerSize),
 9      _consumerSize(consumerSize),
10      _producers(_producerSize, NULL),
11      _consumers(_consumerSize, NULL)
12 {
13     for(std::vector<Producer *>::iterator iter = _producers.begin();
14         iter != _producers.end();
15         ++ iter)
16         *iter = new Producer(_buffer);
17
18     for(std::vector<Consumer *>::iterator iter = _consumers.begin();
19         iter != _consumers.end();
20         ++ iter)
21         *iter = new Consumer(_buffer);
22 }
23
24 WorkShop::~WorkShop()
25 {
26     for(std::vector<Producer *>::iterator iter = _producers.begin();
27         iter != _producers.end();
28         ++ iter)
29         delete *iter;
30
31     for(std::vector<Consumer *>::iterator iter = _consumers.begin();
32         iter != _consumers.end();
33         ++ iter)
34         delete *iter;
35 }
36
37 void WorkShop::startWork()
38 {
39     for(std::vector<Producer *>::iterator iter = _producers.begin();
40         iter != _producers.end();
41         ++ iter)
42         (*iter)->start();
43
44     for(std::vector<Consumer *>::iterator iter = _consumers.begin();
45         iter != _consumers.end();
46         ++ iter)
47         (*iter)->start();
48
49     for(std::vector<Producer *>::iterator iter = _producers.begin();
50         iter != _producers.end();
51         ++ iter)
52         (*iter)->join();
53
54     for(std::vector<Consumer *>::iterator iter = _consumers.begin();
55         iter != _consumers.end();
56         ++ iter)
57         (*iter)->join();
58 }

在startWork函数中, 我们先将每个线程的指针调用start()函数,将线程开启, 当我们退出进程后,再调用join()函数将每个线程关闭。

测试代码如下:

1 #include "WorkShop.h"
2
3 int main(int argc, const char *argv[])
4 {
5     WorkShop a(5, 10, 15);
6     a.startWork();
7     return 0;
8 }

编译时要注意,需要的各个cpp文件在前面几篇文章中已经列出,请自行下载尝试。

时间: 2024-10-11 16:29:47

Linux组件封装(五) WorkShop的封装的相关文章

Linux组件封装(五)一个生产者消费者问题示例

生产者消费者问题是计算机中一类重要的模型,主要描述的是:生产者往缓冲区中放入产品.消费者取走产品.生产者和消费者指的可以是线程也可以是进程. 生产者消费者问题的难点在于: 为了缓冲区数据的安全性,一次只允许一个线程进入缓冲区,它就是所谓的临界资源. 生产者往缓冲区放物品时,如果缓冲区已满,那么需要等待,一直到消费者取走产品为止. 消费者取走产品时,如果没有物品,需要等待,一直到有生产者放入为止. 第一个问题属于互斥问题,我们需要使用一把互斥锁,来实现对缓冲区的安全访问. 后两个属于同步问题,两类

Linux组件封装之五:生产者消费者问题

生产者,消费者问题是有关互斥锁(MutexLock).条件变量(Condition).线程(Thread)的经典案例: 描述的问题可以叙述为 生产者往buffer中投放产品,而消费者则从buffer中消费产品. 生产着消费者问题的难点在于: 为了缓冲区数据的安全性,一次只允许一个线程进入缓冲区投放或者消费产品,这个buffer就是所谓的临界资源. 生产者往缓冲区中投放产品时,如果缓冲区已满,那么该线程需要等待,即进入阻塞状态,一直到消费者取走产品为止. 相应的,消费者欲取走产品,如果此时缓冲区为

嵌入式linux C++语言(三)——封装(Encapsulation)

嵌入式linux C++语言(三)--封装(Encapsulation) 一.封装简介 C语言等面向过程编程中,数据以及数据的相关操作函数都是分离的独立个体:在C++等面向对象编程中,数据以及数据的相关操作被设计为对象,对象包括属性(数据)和操作(函数),两者共同构成对象实体(即类实体).面向对象编程使程序更模块化,更易读易写,提升了代码重用到一个更高的层次. 面向对象编程中,数据和数据的操作封装为了对象.封装可以隐藏实现细节,使得代码模块化,是把过程和数据包围起来,对数据的访问只能通过已定义的

关于linux上cron服务的python封装工具

关于cron:定时任务服务,一般linux自带且已启动.(pgrep cron查看cron服务是否启动了.) 关于plan:一个通过python来定制cron服务的工具.其官网:http://plan.readthedocs.org/ plan的使用例子: 例子1: from plan import Plan cron = Plan() output = dict(stdout='~/stdout.log', stderr='~/stderr.log') cron.command('date',

linux试题 (五)

唉,堕落了几天,我又变好了.傻逼技术面试官才会考运维人员程序的问题!运维人员多累啊,数据库,安全.linux服务.网络管理,忙的过来吗?还拿程序为难人!笔试多半挂了,大公司离我又远了,哎... linux面试(五) 201   Shell循环语句有哪些? 答:for do done ;if then fi ;case 语句.while do done.until 202 用SHELL模拟LVS,脚本怎么写 答:步骤有点长,推荐购买<构建高可用linux服务器>-余洪春,这本书写的很详细 203

马哥linux作业第五周&#39;

1.显示当前系统上root.fedora或user1用户的默认shell: egrep "^(root|fedora|user1)\>" /etc/passwd |cut -d: -f1,7 root|fedora|user1表示三者符合其一的选择条件 ()使其归组 ^表示以后面归组的条件开头 \>表示以空字符截断此前的条件字符,即后跟其它字符的单词将不匹配 2.找出/etc/rc.d/init.d/functions文件中某单词后面跟一组小括号的行,形如:hello():

攻城狮在路上(叁)Linux(十五)--- 文件与目录的默认权限与隐藏权限

一.文件默认权限:umask <==需要被减去的权限. 1.umask指的是当前用户在新建文件或者目录时的默认权限,如0022; 2.默认情况下,用户创建文件的最大权限为666; 创建目录的最大权限为777. 3.最终权限 = 最大权限 - umask; <== 此处注意并非是数值直接相减. 4.设置umask: umask 002; 5.由上述条件,自己判断用户新建文件或目录的最终权限. 二.文件的隐藏属性: chattr.lsattr , 隐藏属性对于系统安全有很大的帮助. chattr

随笔--安装Linux系统的五个理由

看到一篇网文--你应该安装Linux系统的五个理由: http://os.51cto.com/art/201607/514876.htm 感到有些奇怪. 安装操作系统,是谁的事? 我所买的计算机,都是装有正版的 WIN7.WIN8. 用的好好的. 难道,还用我自己重新安装 Linux ? 也许,小编买到的,是没有操作系统的裸机? 如果我需要用 Linux 系统,我直接就买这种计算机即可. 那还用我自己装系统? 小编所发表的文章,毫无道理.

linux关机重启五种方法(sysrq shutdown halt init ipmi)

linux关机重启五种方法(sysrq shutdown halt init) 当前版本 cat /etc/debian_version 5.0.1 一.linux关机命令(前三种) 1.shutdown -h now(-h:halt after shutdown.) halt init 0 2.linux重启命令 shutdown -r(-r:reboot after shutdown.) reboot init 6 二.特殊情况重启和关机(能ping通 上述命令无法使用情况下 也就是系统挂起