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)获取。

  • 相关阅读:
    UISegmentedControl字体大小,颜色,选中颜色,左边椭圆,右边直线的Button 解决之iOS开发之分段控制器UISegmentedControl
    如何看待 Kotlin 成为 Android 官方支持开发语言?
    (腾讯视频)iOS开发之视频根据url获取第一帧图片,获取任一帧图片
    Swift 开源项目精选
    iOS数组排序 请求后,数组元素的排序 时间戳,最热,点赞数等
    iOS开发:UITableView的优化技巧-异步绘制Cell
    PHP 时间戳 转时间 for ios 8*3600
    mysql中子查询更新,得用别名表
    Java NIO系列教程(三) Buffer(转)
    深入理解ByteBuffer(转)
  • 原文地址:https://www.cnblogs.com/xfxu/p/4008703.html
Copyright © 2011-2022 走看看