🌏博客主页:PH_modest的博客主页
🚩当前专栏:Linux跬步积累
💌其他专栏:
🔴 每日一题
🟡 C++跬步积累
🟢 C语言跬步积累
🌈座右铭:广积粮,缓称王!
文章目录
创建文件
首先创建一个.hpp文件和一个.cc文件,.hpp文件内进行对thread的封装,然后在.cc文件下进行测试。
提示:.hpp文件是类似于.h文件,更多用于C++中,用于和C语言的进行区分,.hpp文件内包含类、模版、函数、宏的定义和声明,它允许在多个源文件中共享代码,避免重复编写。
.hpp文件的创建、thread类的函数定义
cpp
#ifndef __THREAD_HPP__ //避免头文件重复包含
#define __THREAD_HPP__
#include<iostream>
#include<string>
#include<pthread.h>
#include<functional>
#include<unistd.h>
//命名空间
namespace ThreadModule
{
template<class T>
using func_t = std::function<void(T&)>;//模版方法,下面参数的定义也要带模版
template<class T>
class Thread
{
public:
Thread(func_t<T> func,const T &data,const std::string &name="none_name")
:_func(func),_data(data),_threadname(name),_stop(true)
{}
bool Start()//启动并创建线程
{}
void Detach()//分离线程
{}
void Join()//等待线程
{}
void Stop()//终止线程
{}
~Thread()
{}
private:
pthread_t _tid;
std::string _threadname;
T _data;
func_t<T> _func;
bool _stop;
};
}//namespace ThreadModule
#endif
.cc文件的创建
cpp
#include "Thread.hpp"
#include <iostream>
#include<vector>
using namespace ThreadModule;
const int num=10;
int main()
{
//1.创建一批线程
//2.启动一批线程
//3.等待一批线程
return 0;
}
.hpp内thread类基础函数的实现
cpp
#ifndef __THREAD_HPP__
#define __THREAD_HPP__
#include<iostream>
#include<string>
#include<pthread.h>
#include<functional>
#include<unistd.h>
//命名空间
namespace ThreadModule
{
template<class T>
using func_t = std::function<void(T&)>;//模版方法,下面参数的定义也要带模版
template<class T>
class Thread
{
public:
void Excute()
{
_func(_data);
}
public:
Thread(func_t<T> func,const T &data,const std::string &name="none_name")
:_func(func),_data(data),_threadname(name),_stop(true)
{}
static void* Threadroutinue(void* args)//类成员函数,形参是有this指针的!!!,不满足pthread_create的传参要求。所以需要加static
{
Thread<T>* self=static_cast<Thread<T>*>(args);
self->Excute();
return nullptr;
//会报错,因为访问成员函数前需要加this指针,但是static没有this指针
//_func(_data);
//测试代码
// while(true)
// {
// std::cout<<"I am new thread..."<<std::endl;
// sleep(1);
// }
}
bool Start()
{
int n = pthread_create(&_tid,nullptr,Threadroutinue,this);
if(!n)
{
_stop=false;
return true;
}
else
{
return false;
}
}
void Detach()
{
if(!_stop)
pthread_detach(_tid);
}
void Join()
{
if(!_stop)
pthread_join(_tid,nullptr);
}
void Stop()
{
_stop=true;
}
std::string name()
{
return _threadname;
}
~Thread()
{}
private:
pthread_t _tid;
std::string _threadname;
T _data;
func_t<T> _func;
bool _stop;
};
}//namespace ThreadModule
#endif
知识点1:
其他函数的实现只需要调用pthread库就可以了,但是我们使用pthread_create()
函数来调用成员函数Threadroutinue()
时,如果Threadroutinue()
前面不加static则会报错,因为pthread_create()
第三个参数是一个返回值为void*,参数为void*的一个函数,而成员函数会隐藏一个this指针,这就会导致出错,因此我们只需要加上static,那么成员函数就不会带有this指针了。
但是当我们想用成员函数Threadroutinue()
调用成员变量_func
,来使用外部传递的函数时,因为没有this指针,导致我们无法调用,这又应该如何解决呢?
于是我们可以再定义一个函数Excute()
,我们使用Excute()
来调用_func
,然后pthread_create()
函数的第四个参数传递this指针,这样Threadroutinue()
就可以用传递的this指针调用Excute()
函数了,这样就可以完美解决问题。
知识点2:
我们可以使用#include<functional>
头文件内的function函数来定义一个函数指针,类似于文中的std::function<void(T&)>
,这里的void表示函数的返回值,T&表示函数的参数 。因此我们之后就可以传递void Printf(int &data)
函数给线程了。
.cc内thread类的简单调用
cpp
#include "Thread.hpp"
#include <iostream>
#include<vector>
using namespace ThreadModule;
void Printf(int &data)
{
while(data)
{
std::cout<<"hello I am myself thread,data:"<<data--<<std::endl;
sleep(1);
}
}
const int num=10;
int main()
{
std::vector<Thread<int>> threads;
//1.创建一批线程
for(int i=0;i<num;i++)
{
std::string name = "thread-"+std::to_string(i+1);
threads.emplace_back(Printf,10,name);
}
//2.启动一批线程
for(auto &thread:threads)
{
thread.Start();
}
//3.等待一批线程
for(auto &thread:threads)
{
thread.Join();
std::cout<<"wait thread done...thread is"<<thread.name()<<std::endl;
}
return 0;
}
运行演示
总结
本篇博客没有过多讲解代码,这里是默认大家都能看懂的,主要是为了讲解一下文中的两个知识点,如果对代码部分有疑问可以看看我的前几篇有关线程的博客。