Linux组件封装(三) Thread的封装

声明代码如下:

 1 #ifndef THREAD_H
 2 #define THREAD_H
 3
 4 #include "NonCopyable.h"
 5 #include <pthread.h>
 6 #include <sys/types.h>
 7
 8 class Thread : NonCopyable
 9 {
10 public:
11     Thread();
12     ~Thread();
13
14     void start();
15     void join();
16
17     pthread_t getThreadId() { return _threadId; }
18     virtual void run()=0;
19
20 private:
21     static void *func(void *arg);
22
23     pthread_t _threadId;
24     bool _isRun;
25 };
26
27 #endif

为了调用pthread_create创建线程,我们往里面注册的不能是一个成员函数,因为成员函数含有一个隐式参数,导致函数的指针类型并不是void *(*start_routine) (void *),所以我们采用了static函数

static函数无法访问某一对象的成员,所以我们在调用pthread_create时,将this指针作为回调函数的参数

这个Thread不提供detach函数,因为我们在析构函数中做了如下的处理,如果Thread对象析构,线程还在运行,那么需要将Thread设置为detach状态

大部分逻辑都是固定的,用户只需要改变run里面的代码即可,于是我们将run设置为纯虚函数,让用户继承Thread类

cpp代码实现如下:

 1 #include "Thread.h"
 2 #include <iostream>
 3 #include <assert.h>
 4 #include <unistd.h>
 5 #include <pthread.h>
 6 #include <sys/syscall.h>
 7 using namespace std;
 8
 9 Thread::Thread()
10     :_threadId(0),
11      _isRun(false)
12 { }
13
14 Thread::~Thread()
15 {
16     if(_isRun)
17         pthread_detach(_threadId);
18 }
19
20
21 void *Thread::func(void *arg)
22 {
23     Thread *p = static_cast<Thread *>(arg);
24     p->run();
25     return NULL;
26 }
27
28
29 void Thread::start()
30 {
31     pthread_create(&_threadId, NULL, Thread::func, this);
32     _isRun = true;
33 }
34
35 void Thread::join()
36 {
37     assert(_isRun);
38     pthread_join(_threadId, NULL);
39     _isRun = false;
40 }

我们采用继承的方式使用这个类。测试代码如下:

 1 #include "Thread.h"
 2 #include <iostream>
 3 #include <unistd.h>
 4 using namespace std;
 5
 6 class MyThread : public Thread
 7 {
 8 public:
 9     void run()
10     {
11         cout << "foo" << endl;
12     }
13 };
14
15 int main(int argc, char const *argv[])
16 {
17     MyThread t;
18     t.start();
19
20     t.join();
21
22     return 0;
23 }
时间: 2024-07-30 13:52:45

Linux组件封装(三) Thread的封装的相关文章

Linux组件封装(三)使用面向对象编程封装Thread

C++11提供了thread,但是过于复杂,我们还是倾向于在项目中编写自己的Thread. Posix Thread的使用这里不再赘述. 重点是这个函数: #include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 第三个参数是一个回调函数,该函数必须返回值为void*,而且只有一个参数,类型

Linux组件封装之三:Thread

本篇我们将讨论线程Thread的封装: 一.线程类(Thread): 注意: 1.线程在默认情况下 是 joinable(可结合状态),需要手工调用 join函数(将其回收),也可以将其设置为detachable(分离状态),线程运行完毕后自动消亡: 2.Thread类采用static函数作为 pthread_create的回调函数,原因在于普通成员函数含有一个隐式参数(该类的对象 本身),所以函数指针类型除了有void*参数外,还有一个 Thread 对象的隐式参数,所以 这就与 void*(

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

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

Linux组件封装(六)——定时器的简单封装

在Linux中,有一种简单的定时器——timerfd,它通过查看fd是否可读来判断定时器时候到时. timerfd中常用的函数有timerfd_create.timerfd_settime.timerfd_gettime,这些函数都相对简单,我们可以到man手册来查看用法. 值得注意的是:create中的参数CLOCK_REALTIME是一个相对时间,我们可以通过调整系统时间对其进行调整,而CLOCK_MONOTIC是一个绝对时间,系统时间的改变不会影响它.在create中,flags一般设置为

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

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

关于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',

C++实现委托机制(三)——lambda表达式封装

C++实现委托机制(三)——lambda表达式封装1.引言:              其实原本没打算写这一章的,不过最后想了想,嗯还是把lambda表达式也一并封装进去,让这个委托也适应lambda表达式的注册.不过在之前还是需要先了解lambda表达式. 2.lambda表达式:              如果大家还有对lambda表达式不了解的可以先去了解lambda表达式的基本语法和用法.这里我们只讲跟lambda表达式封装相关的知识.我们先来看看使用lambda表达式的好处吧:1.la

Struts——三大组件(三)Action

Action Action是Struts中的基础组件.我们学过了Struts的执行流程,处理最终都会调到一个Action类:我们在Action中取得表单数据:进行业务逻辑处理:页面转发.传递等. 一.配置文件 <actionpath="/login" type="struts.LoginAction" name="loginForm" scope="request" > 二.Action代码 生成Action后,当

【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

RAC 工作原理和相关组件(三) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体系的总结,一则进行回顾复习,另则便于查询使用.本图文文档亦源于此.阅读Oracle RAC安装与使用教程前,笔者先对这篇文章整体构思和形成进行梳理.由于阅读者知识储备层次不同,我将从Oracle RAC安装前的准备与规划开始进行整体介绍安装部署Oracle RAC.始于唐博士指导,对数据库集群进行配置安装,前