【Linux课程学习】:锁封装(Mutex)线程封装(Thread),this指针

【Linux课程学习】:锁封装(Mutex)线程封装(Thread),this指针

🎁个人主页:我们的五年

🔍系列专栏:Linux课程学习 

🌷追光的人,终会万丈光芒

🎉欢迎大家点赞👍评论📝收藏⭐文章

Linux学习笔记:
 https://blog.ZEEKLOG.net/djdjiejsn/category_12669243.html

前言:

C++中已经封装了线程,在这里我们自己对线程进行封装,能更好的理解C++中的线程封装。我们自己封装的线程肯定比不了C++线程库中的封装,但是也能锻炼我们。

目录

下面关于锁的封装看看下面的:

1.访问内部私有成员变量

2.Thread成员变量:

2.1.首先肯定是线程的tid:pthread_t _tid。

2.2.进程的pid:pid_t _pid;。

2.3.线程的状态:

2.4.是否被分离:

2.5.线程名字

2.6.执行的方法:

3.内部成员方法:

3.1构造函数:

3.2Start函数:

3.3Stop函数:

 4.整体代码:


下面关于锁的封装看看下面的:

Lockguard的构造函数加锁,析构函数解锁,用起来很方便。

namespace MutexModule { class Mutex { private: Mutex(const Mutex &) = delete; const Mutex &operator=(const Mutex &) = delete; public: Mutex() { int n = ::pthread_mutex_init(&_mutex, nullptr); (void)n; } void Lock() { int n = ::pthread_mutex_lock(&_mutex); (void)n; } void UnLock() { int n = ::pthread_mutex_unlock(&_mutex); (void)n; } pthread_mutex_t *LockPtr() { return &_mutex; } ~Mutex() { int n = ::pthread_mutex_destroy(&_mutex); (void)n; } private: pthread_mutex_t _mutex; }; class LockGuard { public: LockGuard(Mutex &mtx) : _mtx(mtx) { _mtx.Lock(); } ~LockGuard() { _mtx.UnLock(); } private: Mutex &_mtx; }; }

1.访问内部私有成员变量

1.类中的static函数为什么不能直接访问内部成员变量?

因为默认没有传this指针。所以static函数参数中有this指针的时候,还是可以访问的,此时this(对象)指针不能省略。

2.外部函数不能访问私有成员?

没有默认传递this指针,没有访问权限。声明是类的友元函数的时候,也是可以访问的。

代码:

#include <iostream> using namespace std; class Solution { public: Solution() :_n(1111) { } friend static void test(Solution* t); static void func() { } static void a() { //可以访问静态成员方法,访问权限给到了private // 就是没有默认传递this指针而已 func(); _m = 11; } static void b(Solution* t) { //可以访问静态成员方法,访问权限给到了private // 就是没有默认传递this指针而已 t->_n = 555; t->_m; t->func(); } private: int _n; static int _m; }; void test(Solution* t) { //能访问是传递了Solution对象,是Solution类的友元 //friend static void test(Solution*& t); t->_n = 222; }

2.Thread成员变量:

2.1.首先肯定是线程的tid:pthread_t _tid。

2.2.进程的pid:pid_t _pid;。

pthread_t _tid;

pid_t _pid;

2.3.线程的状态:

enum class STATUS

{

       RUNNING=1,

       STOP,

       NEW     //新的线程的状态

};

STATUS _status;

表示线程的状态,NEW表示新的线程,还没有进行Start操作时的状态信息。

2.4.是否被分离:

线程默认是没有被分离的,而且只有分离和没有被分离两种情况,bool类型。

bool _joinable;  //是否被分离

join命名就是,当joinable为true的时候,主线程要进行join,为false的时候,就不要进行join。
void EnableDetach() { //状态变为false,新的线程默认为true _joinable=false; } void Detach() { EnableDetach(); //线程分离 pthread_detach(_tid); }

2.5.线程名字

为了区分不同的线程可以给线程取个名字。

std::string _name;

名字可以取"thread-num"表示是第几个线程。

2.6.执行的方法:

这里定义的是void(std::string name),返回值为void,参数是string的函数。

using func_t=std::function(void(std::string name));

3.内部成员方法:

3.1构造函数:

_name:

线程名字以"thread-num"来命名,表示第几个线程。所以定义一个static int num进行记录有多少个线程。但是这是临界资源,线程再创建线程,导致方式混乱。

static int num=1;

_joinable:

_joinable默认是没有被分离的,所以是true。

_func:

_func是外部传进来要执行的方法。所以要有func_t 参数。

_status:

为新线程,状态为NEW

_tid:

在线程创建的时候,传到pthread里面进行确定。

Thread(func_t func) :_pid(getpid()) ,_func(func) ,_joinable(true) ,_status(STATUS::NEW) { LockGuard lockguard(_lock); { _name="thread-"+std::to_string(num++); } }

 

3.2Start函数:

先判断是不是没有在RUNNING,如果在RUNNING就返回false。然后创建线程进行执行,状态修改。

static void* Routine(void* args) { Thread* t=static_cast<Thread*>(args); t->_status=STATUS::RUNNING; t->_func(t->Name()); return nullptr; } bool Start() { if(_status!=STATUS::RUNNING) { int n=::pthread_create(&_tid,nullptr,Routine,this); if(n!=0) { //线程创建失败 return false; } return true; } //已经在RUNNING了 return false; }

3.3Stop函数:

bool Stop() { //在运行的时候,才能cancle if(_status==STATUS::RUNNING) { _status=STATUS::STOP; int n=::pthread_cancel(_tid); if(n!=0) { return true; } } return true; }

3.4Join函数,EnableJoin函数:

void EnableDetach() { //状态变为false _joinable = false; } bool Join() { //没有被分离才能join if (_joinable) { int n = ::pthread_join(_tid, nullptr); if (n != 0) return false; _status = STATUS::STOP; return true; } return false; } void Detach() { EnableDetach(); //线程分离 pthread_detach(_tid); }

 4.整体代码:

#pragma once #include <iostream> #include <cstdio> #include <string.h> #include <cstring> #include <pthread.h> #include <functional> #include <unistd.h> #include <sys/types.h> #include "Mutex.hpp" namespace ThreadModule { using namespace MutexModule; using func_t=std::function<void(std::string name)>; static int num=1; enum class STATUS { RUNNING=1, STOP, NEW //新的线程的状态 }; class Thread { private: //执行方法,routine惯例 static void* Routine(void* args) { Thread* t=static_cast<Thread*>(args); t->_status=STATUS::RUNNING; t->_func(t->Name()); return nullptr; } void EnableDetach() { //状态变为false _joinable=false; } public: Thread(func_t func) :_pid(getpid()) ,_func(func) ,_joinable(true) ,_status(STATUS::NEW) { LockGuard lockguard(_lock); { _name="thread-"+std::to_string(num++); } } bool Start() { if(_status!=STATUS::RUNNING) { int n=::pthread_create(&_tid,nullptr,Routine,this); if(n!=0) { //线程创建失败 return false; } return true; } //已经在RUNNING了 return false; } bool Stop() { //在运行的时候,才能cancle if(_status==STATUS::RUNNING) { _status=STATUS::STOP; int n=::pthread_cancel(_tid); if(n!=0) { return false; } return true; } return true; } bool Join() { //没有被分离才能join if(_joinable) { int n=::pthread_join(_tid,nullptr); if(n!=0) return false; _status=STATUS::STOP; return true; } return false; } void Detach() { EnableDetach(); //线程分离 pthread_detach(_tid); } std::string Name() {return _name;} bool JoinAble(){return _joinable;} ~Thread() { } private: std::string _name; //线程名字 pthread_t _tid; //线程tid pid_t _pid; //线程属于哪个进程pid STATUS _status; //线程的状态 bool _joinable; //是否被分离 func_t _func; //线程执行的方法 Mutex _lock; //锁进行保护 }; }
Start
Stop
Join
EnableJoin
Name
JoinAble
感谢阅读,相信美好的事情即将发生。

Read more

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

摘要:本文聚焦OpenClaw从测试环境走向生产环境的核心痛点,围绕“性能优化、安全加固、监控运维”三大维度展开实操讲解。先明确生产环境硬件/系统选型标准,再通过硬件层资源管控、模型调度策略、缓存优化等手段提升响应速度(实测响应效率提升50%+);接着从网络、权限、数据三层构建安全防护体系,集成火山引擎安全方案拦截高危操作;最后落地TenacitOS可视化监控与Prometheus告警体系,配套完整故障排查清单和虚拟实战案例。全文所有配置、代码均经实测验证,兼顾新手入门实操性和进阶读者的生产级部署需求,帮助开发者真正实现OpenClaw从“能用”到“放心用”的跨越。 优质专栏欢迎订阅! 【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】【YOLOv11工业级实战】 【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】【数字孪生与仿真技术实战指南】 【AI工程化落地与YOLOv8/v9实战】【C#工业上位机高级应用:高并发通信+性能优化】 【Java生产级避坑指南:

By Ne0inhk
ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

🎬 渡水无言:个人主页渡水无言 ❄专栏传送门: 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》 ❄专栏传送门: 《freertos专栏》《STM32 HAL库专栏》 ⭐️流水不争先,争的是滔滔不绝  📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生 | 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生 在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连 目录 前言  一、实验基础说明 1.1、互斥体简介 1.2 本次实验设计思路 二、硬件原理分析(看过之前博客的可以忽略) 三、实验程序编写 3.1 互斥体 LED 驱动代码(mutex.c) 3.2.1、设备结构体定义(28-39

By Ne0inhk
Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 后端工程师扔给你一个 Swagger (OpenAPI) 文档地址,你会怎么做? 1. 对着文档,手写 Dart Model 类(容易写错字段类型)。 2. 手写 Retrofit/Dio 的 API 接口定义(容易拼错 URL)。 3. 当后端修改了字段名,你对着报错修半天。 这是重复劳动的地狱。 swagger_dart_code_generator 可以将 Swagger (JSON/YAML) 文件直接转换为高质量的 Dart 代码,包括: * Model 类:支持 json_serializable,带 fromJson/

By Ne0inhk
Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

文章目录 * 前言 * make/makefile * 文件的三个时间 * Linux第一个小程序-进度条 * 回车和换行 * 缓冲区 * 程序的代码展示 * git指令 * 关于gitee * Linux调试器-gdb使用 * 作业部分 前言 做 Linux 开发时,你是不是也遇到过这些 “卡脖子” 时刻?写 makefile 时,明明语法没错却报错,最后发现是依赖方法行没加 Tab;想提交代码到 gitee,记不清 git add/commit/push 的 “三板斧”,还得反复搜教程;用 gdb 调试程序,输了命令没反应,才想起编译时没加-g生成 debug 版本;甚至连写个进度条,都搞不懂\r和\n的区别,导致进度条乱跳…… 其实这些问题,

By Ne0inhk