对posix线程机制的c++封装实现

Linux轻量HTTP下载器:C++实现,支持断点续传+多线程并发 一个开箱即用的Linux命令行HTTP下载工具,纯C++编写,不依赖第三方网络库,编译后体积小、运行高效。核心能力包括断点续传——下载中断后可从上次进度继续,节省带宽和时间;多线程并发下载——将单个文件切片分发给多个线程并行获取,显著提升大文件下载速度。源码结构清晰,含CSocket网络封装模块(支持TCP连接管理、超时控制)、主下载调度逻辑(http_main.cc)、简易说明文档(www.pudn.com.txt)及可执行文件构建脚本。适配标准POSIX环境,GCC编译即可运行,适合嵌入式设备、服务器后 阅读详情
 一直感觉Java的framework是学习OO设计非常优秀的范例。在Java中有对Thread非常方便的封装,重用起来十分方便,于是自己也想用C++对posix的pthread接口做一个类似的封装。
 
    事情没有想象那么简单,主要的问题出现在C和C++之间函数指针的转换上:
 
    来看下面一个类的定义:
 
typedef void*(*pFunc)(void*);
class Thread
{
    public:
    static void* run(void*)
    {
        cout<<"fn"<<endl;
    }
    void* runMember(void*)
    {
        cout<<"fn"<<endl;
    }
    virtual void* runVirtual(void*)
    {
        cout<<"fn"<<endl;   
    }
};
void pthread_create(pFunc){...}
 
    这里class Thread中有三个函数,一个static的,一个member,一个虚函数。请问,三个函数中哪一个可以作为参数传给pthead_create(pFunc)?
 
    C++语法定义不能强制类型转换的语法,一般都是编译器无法实现的语法。这里static void* run(void*)可以强制转换为C指针,而后两者不行。
 
    原因是对于runMember成员函数,编译器在编译时会将函数的第一个参数默认的分配给this指针。故C++与C函数指针实际上类型不匹配,编译器当然也无法把第一个this指针给你去了,否则函数里如果要调成员就更麻烦了。
    而对于runVirtual(void*),一来有同样的函数参数不匹配问题,二来对于含有virtual function的class,C++编译器会自动在类的内存空间内生成虚函数表,同时cpp编译器采取的标识虚函数的方式是为每一个虚函数保存一个id,调用虚函数通过虚函数表base+id的方式得到真实函数入口。故这里的runVirtual根据不同的编译实现,或许是虚函数表base值,或许是虚函数id。
    所以对于一个Thread类,可以这样实现:
(
   参考jdk的设计,thread可以通过两种方式创建,一是传函数指针(runnable接口)的方式直接创建THread对象,二是通过继承并扩展thread中run接口的方式创建thread。
)
//省略了错误处理的code
 
typedef void*(*PTHREADFUNC)(void*)
 
class Thread
{
public:
   Thread(PTHREADFUNC pTFunc):m_tid(0)
   {
       m_pthis = NULL;
       pthead_create(&m_tid,NULL,pTFunc,NULL);
       pthread_detach(m_tid);
   }
   Thread():m_tid(0)
   {
       m_pthis = this;
       pthead_create(&m_tid,NULL,&Thread::ThreadRun,NULL);
       pthread_detach(m_tid);
   }
    static void* ThreadRun(void*)
   {
       if(NULL != m_pthis)
       {
           m_pthis->run();
       }
   }
   virtual void run()=0;
private:
   staitc Thread *m_pthis;
   pthread_t m_tid;
};
 Thread * Thread::m_pthis = NULL;
 
 
这里通过一个adapter function : ThreadRun ,充当了C与C+代码中的Adapter。
用户类只需要扩展Thread类实现run()这个virtual方法,并创建类的实例就能实际线程。
 
当然上面这个Thread类还有很多问题:如1.不是线程安全的。因为用了一个static变量m_pthis保存this指针,所以需要使用者在创建自定义对象的前后在应用层中加锁保护。
2.并没有实现Java中那样的Runnable接口:像Java中那样通过对象基类(Interface)的方式传递回调函数是一种非常优雅的方法。要实现Runnable接口,可以在Runnable类中做和上面Thread类似的方法,用adapter function实现C对Cpp虚函数的调用。

再贴一个加锁版本的部分代码:

typedef void*(*pTFUNC)(void*);

class Thread
{
 public:
  Thread();
  Thread(pTFUNC runnable);
  virtual void run();
  static void* runGlobal(void*);
  static int detach(pthread_t tid);
  static int join(pthread_t tid,void **status);
  static void sleep(unsigned long);
  static void nsleep(unsigned long,unsigned long);
  static pthread_t self_id();
  pthread_t getThreadID();
  int getErrorCode();
 protected:
  void start();
  pTFUNC m_pRunnable;
  pthread_t m_tid;
  bool m_avaliable;
  int m_errorcode;
  static Thread* m_pthis;
  static pthread_mutex_t m_mutex;
 
};

Thread* Thread::m_pthis=NULL;
pthread_mutex_t Thread::m_mutex=PTHREAD_MUTEX_INITIALIZER;
Thread::Thread()
{
  m_pRunnable = NULL;
  m_tid = 0;
  m_avaliable = false;
  m_errorcode=0;
  pthread_mutex_lock(&m_mutex);
  m_pthis = this;
  start();
}

Thread::Thread(pTFUNC pRunnable)
{
  m_pRunnable = pRunnable;
  m_tid=0;
  m_avaliable = false;
  m_errorcode=0;
  m_pthis = this;
  start();
}

void Thread::run()
{
  return;
}

void* Thread::runGlobal(void *args)
{
  Thread *pLocal = m_pthis;
  pthread_mutex_unlock(&m_mutex);
  if(NULL != pLocal )
  {   
    pLocal->run();
  }
  return (void*)0;
}
void Thread::start()
{
  if( NULL!=m_pRunnable )
  {
    m_errorcode = pthread_create(&m_tid,NULL,m_pRunnable,NULL);
  }
  else
  {
    m_errorcode = pthread_create(&m_tid,NULL,(&Thread::runGlobal),NULL);
  }
  if(0==m_errorcode)
  {
    detach(m_tid);
    m_avaliable = true;
  }
  #ifdef _DEBUG
  printf("tid:%u,errorcode:%u,selfid:%u/n",m_tid,m_errorcode,pthread_self());
  #endif
}
开源高性能C++并发编程库Genesis实战应用 Genesis C++ Library 遵循“抽象而不牺牲性能”的设计原则,采用现代C++(C++17/20)特性构建高内聚、低耦合的模块化架构。其核心通过封装系统级API(如pthreads、文件I/O、内存映射)提供统一接口,屏蔽平台差异。// 示例:线程启动的高级抽象public:void run() override { /* 用户任务逻辑 */ }t.start();// 内部封装pthread_create与异常安全处理该库在。 阅读详情

相关推荐

C++多线程基类C++多线程基类C++多线程基类

C++多线程基类C++多线程基类C++多线程基类C++多线程基类C++多线程基类C++多线程基类C++多线程基类C++多线程基类C++多线程基类

linux上,使用POSIX线程好还是C++11的线程库好

如果你正在开发一个需要在多种平台上运行的应用程序,并且希望使用一个简单的、易于理解的线程模型,那么C++11的线程库可能是一个更好的选择。C++11线程库:C++11的线程库提供了更高级别的抽象,它隐藏了许多底层细节,使得线程的使用更加简单和直观。C++11线程库:C++11的线程库是C++标准的一部分,因此它应该在所有支持C++11或更高版本的平台上可用,包括Windows、Linux和macOS。C++11线程库:C++11线程库与C++的异常处理机制紧密结合,使得错误处理和异常安全性更高。

slty_123的博客 241

从零搭建uniapp+vue3+ts+tailwindcss多端兼容开发环境

本文详细介绍了如何从零搭建uniapp+vue3+ts+tailwindcss多端兼容开发环境,包括环境准备、TailwindCSS集成、小程序兼容性解决方案以及样式优化技巧。通过实战步骤和常见问题解答,帮助开发者快速掌握这套技术栈,提升开发效率。

weixin_28693309的博客 323

C++之多线程(posix简介)

from:百度百科 1.简介 POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。Windows操作系统也有其移植版pthreads-win32。 2.作用 线程库实行了POSIX线程标准通常称为Pt

Lavi的专栏 2032

高德地图JSAPI中旋转Marker点标签图片时候,且不旋转lable内容方法。

高德地图JSAPI中旋转Marker点标签图片时候,且不旋转lable内容方法

weixin_42960380的博客 2500

GB28181安防平台未授权访问漏洞:原理、复现与修复指南

未授权访问漏洞是Web安全中常见的访问控制缺陷,其本质在于应用在提供对敏感功能或数据的访问前,未能对请求者的身份和权限进行充分验证。从技术原理上看,这类漏洞常源于拦截器配置错误、安全注解遗漏或自定义校验逻辑缺陷,导致本应受保护的API接口被意外暴露。在工程实践中,此类漏洞危害巨大,攻击者无需登录即可直接访问系统核心接口,可能引发敏感信息泄露、权限提升甚至系统接管。尤其在安防监控、物联网管理平台等场景中,一旦涉及用户管理接口(如`/api/user/**`),风险会急剧放大。本文以GB28181视频监控管理平

weixin_30271335的博客 438

posix和c++11线程池

posix和c++11线程池

360

【DDSCAT——离散偶极近似仿真程序05】模型设计Matlab代码:多核壳球 、多核壳圆柱

简洁明了,后面及部分给出的都是模型设计的Matlab代码,这些代码都来自于一篇文章:Chin C W S. Localized Surface Plasmon Resonance with the use of Silver and Titanium Oxide Nanostructures[J]. 2011. 一、设计多个核壳球形结构 1)Matlab代码 ...

XD_Yangf的博客 4257

C++11和POSIX线程库线程互斥与线程同步编程(锁,条件变量,信号量)

文章目录完成两个线程通过条件变量实现交替打印的控制锁+条件变量二元信号量对比一下条件变量和二元信号量按序打印条件变量版二元信号量版生产者消费者条件变量+锁(C++11)多元信号量(有点绕)条件变量和多元信号量的对比 前言:用一些习题来说明这三个东西怎么写。说实话,编写线程同步代码并不简单。 完成两个线程通过条件变量实现交替打印的控制 锁+条件变量 不管是C++11还是POSIX,套路都是一样的 首先要强调的两点: 1.缓冲区队列是临界资源,因此进入就要加锁 2.条件变量是临界资源,进行判断条件是否满足和

m0_51641706的博客 1421

Splunk CVE-2018-11409认证绕过漏洞深度解析

Splunk作为主流企业级日志分析平台,其Web管理接口的认证机制直接关系到整个安全运营体系的可信边界。CVE-2018-11409本质上是REST API路由层会话校验缺失引发的未授权访问问题,根源在于`/en-US/splunkd/__raw/`路径绕过了splunkweb与splunkd之间的信任链验证,导致配置文件、用户哈希、App源码等敏感信息明文泄露。该漏洞凸显了Web接口权限模型设计失守的风险,尤其在默认配置未加固、HTTPS未启用、初始密码未修改的生产环境中危害急剧放大。结合vulfocus

weixin_30875157的博客 597

Java电商秒杀系统性能优化(一)——电商秒杀系统框架回顾

电商秒杀系统框架回顾项目简介外部依赖框架回顾项目要点项目中存在的问题小结 课程是免费的,课程地址如下:SpringBoot搭建电商秒杀项目,课程真的很棒,作者的思路很清晰,建议各位读者可以跟着视频练习一下这个项目; 项目简介 通过SpringBoot快速搭建的前后端分离的电商基础秒杀项目。项目通过应用领域驱动型的分层模型设计方式去完成:用户otp注册、登陆、查看、商品列表、进入商品详情以及倒计时秒...

ghw15221836342的博客 3719

C++后端开发(2.2.3)——POSIX网络API解析

POSIX网络API解析

weixin_43687811的博客 1833

Monorepo与pnpm:前端项目管理的完美搭档

pnpm又称 performant npm,翻译过来就是高性能的npm。Monorepo是一种项目开发与管理的策略模式,它代表"单一代码仓库"(Monolithic Repository)。在Monorepo模式中,所有相关的项目和组件都被存储在一个统一的代码仓库中,而不是分散在多个独立的代码仓库中,这些项目之间还可能会有依赖关系。

m0_68271787的博客 2562

IPerf开源代码中Thread类分析

一点睛 Tread类封装了POSIX标准中的多线程机制,提供了一种简单易用的线程模型。Thread类是IPerf实现中比较重要的类,是IPerf实现多线程并行操作的核心。 二Thread类的定义 1类定义于lib/Thread.hpp中,其实现位于lib/Thread.cpp中。 class Thread { public: Thread( void ); virt...

实践求真知 570

海德汉机床采集数据

海德汉数控系统我一般在高端机床上见得比较多。有好多五轴加工精度比较高的机床都用的是海德汉的系统。市面上常见的有530和640等型号。海德汉的采集还是有点难度的,需要对SDK有深度的了解。

若云流风的专栏 1526

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Linux多线程编程的艺术:封装线程、锁、条件变量和信号量的工程实践

pthread_create函数要求传入一个void *(*start_routine) (void *)类型的函数指针,但为了可以让用户更灵活的使用,我们可以在这里进行一下封装。也就是说希望用户想传什么类型的函数指针都行,那么可以单独设计这样一个函数,如下:

2302_80105876的博客 1449

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++ 线程池实战:从代码解析到多任务处理原理

本文介绍了一个基于POSIX线程库的线程池完整实现方案,包含任务封装、线程池管理和同步机制等关键技术。线程池采用单例模式确保全局唯一性,通过任务队列实现生产者-消费者模型,使用互斥锁和条件变量保证线程安全。核心组件包括:1)Task类封装算术运算任务;2)ThreadPool类管理线程生命周期和任务调度;3)主程序生成随机任务。实现中运用了双重检查锁定、运算符重载等技巧,解决了线程资源复用、任务分发和同步控制等问题,有效提升了多线程程序的性能和稳定性。

zrt123456i的博客 1050

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【Linux】线程从内核到实战:本质、控制逻辑与封装指南

本文深入探讨线程的本质与实现机制。从内核视角看,线程是共享进程地址空间的轻量级进程(LWP),Linux通过复用task_struct结构体实现线程管理。文章详细对比了进程与线程的资源分配差异,指出线程共享虚拟地址空间但拥有私有执行上下文。在内存布局方面,解析了主线程栈与子线程栈的关键区别。最后介绍了POSIX线程库的核心API,包括线程创建、终止、等待与分离等操作,并强调线程封装的最佳实践。全文从理论到实践,系统性地阐述了多线程编程的核心概念与技术要点。

CodeByV的博客 1208

线程概念&&控制

Linux线程与进程管理机制解析 摘要: 本文深入探讨了Linux系统中线程与进程的实现机制。Linux采用轻量级进程(LWP)模拟线程,通过复用进程管理结构(task_struct)实现线程功能,与Windows采用独立线程数据结构的设计形成对比。文章详细分析了线程概念、分页式存储管理、物理内存管理机制,包括页表、页目录结构和TLB快表等核心组件。同时阐述了线程控制方法,包括创建(pthread_create)、终止(pthread_exit)、等待(pthread_join)和分离(pthread_de

MXZSL的博客 864

【Linux系统】深入线程:多线程的互斥与同步原理,封装实现两种生产者消费者模型

本文深入探讨了线程互斥与同步的核心概念。首先解释了临界资源、临界区、互斥和原子性等基本概念,通过count++的例子展示了非原子操作可能导致的数据竞争问题。接着详细介绍了线程互斥的实现机制,包括锁(mutex)的原理和使用方法,强调加锁解锁必须保证原子性,并提供了锁的封装实现。最后引入线程同步的概念,指出单纯互斥可能导致线程饥饿问题,提出需要配合条件变量来实现合理的线程调度顺序。文章通过代码示例和图示,系统性地讲解了多线程编程中保证数据安全的互斥与同步技术。

记录我一步步的学习历程,期待无限进步,向星举目! 1988

c++ 11 thread 初试

最新的 c++11标准整合进了 线程支持。以下写一个小程序測试一下。 測试代码: #include &lt;iostream&gt; #include &lt;thread&gt; void hello(void) { std::cout &lt;&lt; "Hello concurrent world" &lt;&lt; std::endl; } int main(void) ...

weixin_34080903的博客 117

sylar源码解析---线程模块

sylar线程模块

jjkkzzzz的博客 327

Linux《线程(下)》

本文将深入探讨线程编程相关内容。首先补充介绍了线程终止的三种方式:函数返回、pthread_exit调用及pthread_cancel取消线程。其次讲解了pthread_detach函数实现线程分离,使线程结束后自动释放资源。文章还详细解析了线程ID的本质和进程地址空间布局,说明pthread_t实际上是结构体的引用。最后,通过封装pthread库实现了一个面向对象的线程类,包括启动、终止、等待和分离等完整功能。全文循序渐进,从基础概念到实践应用,为后续线程控制学习打下坚实基础。

mljy.博客 1378

线程基本概念

目录 一、线程的基本概念 二、进程和线程的对比 三、重谈地址空间 (1)页表的作用 (2)物理内存管理 四、虚拟到物理地址的转化 页表的原理 五、线程 (1)POSIX 线程库 (2)Linux 中多线程的实现——内核角度 (3)线程接口 线程创建 LWD VS pthread_t 线程等待 线程退出 线程分离  (4)线程切换 (5)Linux 的线程vs 进程 1、进程和线程的区别 2、特点 线程崩溃 六、c++实现线程库

shsbyshdbdhjsk的博客 961

【linux】多线程(九)c++中如何对原生线程进行的封装,STL和智能指针有关的线程安全,自旋锁,读者写者问题(读写锁)

一、c++中如何对原生线程进行的封装 Thread.hpp 基础框架 Run Join main.cc 创建一个线程 main.cc 创建多个线程 二、源代码 Thread.hpp main.cc makefile 三、STL中的线程安全 四、智能指针的线程安全 五、其它常见的各种锁 悲观锁 乐观锁 CAS操作 六、自旋锁 七、读者写者问题(读写锁)

重铸自身根基的博客 1213

线程概念与控制

线程概念,轻量级进程,pthread原生库,分页式存储管理,线程传参,C++封装线程

想学好c++的oMen的博客 586
上一篇: CMap 使用注意说明
下一篇: posix多线程编程简介(转载)
suppercom
博客等级 码龄22年 4粉丝 3原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值