zoukankan      html  css  js  c++  java
  • 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)获取。

  • 相关阅读:
    【Unity3D】使用MD5值,确保本地Sqlite数据库内容没有被篡改
    《Unity3D》通过对象池模式,管理场景中的元素
    NGUI制作 《九宫格》 图片
    NGUI混合FingerGesture《卷二》分离触摸事件
    js的各种获取大小
    sass基础
    js面向对象开发基础
    正则表达式(进阶篇)
    正则表达式(基础篇)
    jquery源码学习(三)—— jquery.prototype主要属性和方法
  • 原文地址:https://www.cnblogs.com/xfxu/p/4008703.html
Copyright © 2011-2022 走看看