Linux组件封装之三:Thread

本篇我们将讨论线程Thread的封装;

 

一、线程类(Thread):

注意:

1、线程在默认情况下 是 joinable(可结合状态),需要手工调用 join函数(将其回收),也可以将其设置为detachable(分离状态),线程运行完毕后自动消亡;

2、Thread类采用static函数作为 pthread_create的回调函数,原因在于普通成员函数含有一个隐式参数(该类的对象 本身),所以函数指针类型除了有void*参数外,还有一个 Thread 对象的隐式参数,所以 这就与 void*(*)(void*)参数不匹配;

类成员的声明 如下:

1 private:
2    void *runInThread (void *); //这里是普通成员函数
3     pthread_t  tid_;
4     bool isRuning_;

 

pthread_create:

 1 void *Thread::runInThread (void *arg)
 2 {
 3     cout << "foo"<< endl;
 4 }
 5 
 6 void Thread::start()
 7 {
 8     //这里的runInThread参数有两个,一个是Thread的一个对象(隐含参数),另一个是void*
 9     //解决办法:将runInThread声明为static函数
10     pthread_create(&tid_, NULL, Thread::runInThread,NULL);//wrong
11     isRuning_ =true;
12 }

 

3)、通过2),我们可以顺利实现线程的创建,但是正如2)中runInThread函数中的语句那样,我们只能执行我们自己定义的行为(如cout语句);而用户需要线程干什么工作我们事先是不知道的,因此,我们通过回调重新实现用户的需求,并且将 run函数设定为纯虚函数。

完整代码如下:

 1 #ifndef THREAD_H_
 2 #define THREAD_H_
 3 
 4 #include "NonCopyable.h"
 5 #include <pthread.h>
 6 #include <assert.h>
 7 #include <iostream>
 8 #include <sys/types.h>
 9 #include <sys>/syscall.h
10 using namespace std;
11 
12 class Thread:NonCopyable
13 {
14     public:
15         Thread();
16         ~Thread();
17 
18         void start();
19         void join();
20         virtual void run()= 0;//纯虚函数
21 
22     private:
23         static void *runInThread (void *);//这里用static声明,表明不属于某一个具体对象,而属于本类。
24         pthread_t  tid_;
25         bool isRuning_;
26 };
27 
28 Thread::Thread()
29     :tid_(0),isRuning_(false)
30 { }
31 
32 Thread::~Thread()
33 {
34     if(isRuning_)
35     {
36         pthread_detach(tid_);
37     }
38 }
39 //这样 我们可以定义自己的MY_Thread类,重新实现run函数,以实现特定的需求
40 void *Thread::runInThread (void *arg)//this指针
41 {
42     Thread *pt = static_cast<Thread*>(arg);//强制转换
43     pt->run(); //调用run函数
44     return NULL;
45 }
46 
47 void Thread::start()
48 {
49     pthread_create(&tid_, NULL, Thread::runInThread,this);//this 指针指向Thread 的本对象
50     isRuning_ =true;
51 }
52 
53 void Thread::join()
54 {
55     assert(isRuning_);
56     pthread_join(tid_,NULL);
57     isRuning_ = false;
58 }
59 pid_t Thread::gettid() const
60 {
61     return syscall(SYS_gettid);
62 }
63 
64 #endif

 

4、Linux中的线程本质上是一个轻量级进程,拥有自己的pid,可以编写gettid,通过syscall(SYS_gettid)获取。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。