1、类与类之间的关系
继承、 关联、聚合、组合、依赖
2、基于对象的线程封装
类和类之间的关系除了继承,还有一些其他的关系,所以可以使用组合与依赖的方式,也就是基于对象的方法(不用使用继承)。因为没有继承,所以需要把Thread类中的抽象方法run()函数通过function与bind的方式进行修改即可。之前的run方法是一个返回类型是void参数为空的函数,现在直接使用bind改变函数的形态,将Thread变为一个非抽象类。然后将任务通过参数传给Thread的构造函数,当然这个参数可以使用对应的数据成员进行接收,这个任务可以交给其他的类来完 成,并且打包给Thread线程进行执行,设计如下:
2.1 Thread.h代码
#ifndef __THREAD_H
#define __THREAD_H
#include<pthread.h>
#include<functional>
using std::function;
using std::bind; //使用bind方法
class Thread{
using ThreadCallback = function<void()>;
public:
Thread(ThreadCallback &&cb);
~Thread();
void start();
void join();
static void* threadFunc(void* args);
private:
pthread_t _thid;
bool _isRunning;
ThreadCallback _cb; // 需要执行的任务
};
2.2Thread.cc代码
#include "Thread.h"
#include<stdio.h>
using namespace std;
Thread::Thread(ThreadCallback &&cb)
:_thid(0)
,_isRunning(false)
,_cb(std::move(cb)) // 注册回调函数
{
}
Thread::~Thread()
{
}
void Thread::start()
{
int ret = pthread_create(&_thid, nullptr, threadFunc, this);
if(ret != 0)
{
printf("pthread_create error");
return;
}
_isRunning = true;
}
void Thread::join()
{
if(_isRunning)
{
int ret = pthread_join(_thid, nullptr);
if(ret != 0)
{
printf("pthread_join error");
return;
}
_isRunning = false;
}
}
//static
void* Thread::threadFunc(void* args)
{
Thread* pthread = static_cast<Thread *> (args);
if(pthread)
{
pthread->_cb();
}else
{
printf("hello");
}
pthread_exit(nullptr);
}
2.3 测试代码Test.cc
include"Thread.h"
#include<stdio.h>
#include <unistd.h>
using namespace std;
class Mytask
{
private:
public:
void process(int x)
{
while (1)
{
printf("Mytask is running!\n");
sleep(x);
}
}
};
void test()
{
Mytask task;
Thread th(bind(&Mytask::process, &task, 1));
th.start();
th.join();
}
int main()
{
test();
return 0;
}
3、难点
1.注册回调函数
2.执行回调函数
3.任务的传递,将任务用bind改变函数形态,交给参数cb(右值引用),再在构造函数中将其初始化。