欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > 【Linux跬步积累】——thread封装

【Linux跬步积累】——thread封装

2025/2/27 6:23:15 来源:https://blog.csdn.net/PH_modest/article/details/145294909  浏览:    关键词:【Linux跬步积累】——thread封装

🌏博客主页:PH_modest的博客主页
🚩当前专栏:Linux跬步积累
💌其他专栏:
🔴 每日一题
🟡 C++跬步积累
🟢 C语言跬步积累
🌈座右铭:广积粮,缓称王!

文章目录

  • 创建文件
    • .hpp文件的创建、thread类的函数定义
    • .cc文件的创建
  • .hpp内thread类基础函数的实现
  • .cc内thread类的简单调用
  • 运行演示
  • 总结


创建文件

首先创建一个.hpp文件和一个.cc文件,.hpp文件内进行对thread的封装,然后在.cc文件下进行测试。

提示:.hpp文件是类似于.h文件,更多用于C++中,用于和C语言的进行区分,.hpp文件内包含类、模版、函数、宏的定义和声明,它允许在多个源文件中共享代码,避免重复编写。

.hpp文件的创建、thread类的函数定义

#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文件的创建

#include "Thread.hpp"
#include <iostream>
#include<vector>using namespace ThreadModule;const int num=10;int main()
{//1.创建一批线程//2.启动一批线程//3.等待一批线程return 0;
}

.hpp内thread类基础函数的实现

#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类的简单调用

#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;
}

运行演示

在这里插入图片描述

总结

本篇博客没有过多讲解代码,这里是默认大家都能看懂的,主要是为了讲解一下文中的两个知识点,如果对代码部分有疑问可以看看我的前几篇有关线程的博客。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com