当前位置: 首页 > news >正文

学习嵌入式的第二十八天——线程

线程的设计框架  posix

创建多线程 ==》线程空间操作 ===》线程资源回收

线程与进程的关系

优点: 比多进程节省资源,可以共享变量。

概念:线程是轻量级进程,一般是一个进程中的多个任务。
进程是系统中最小的资源分配单位.
线程是系统中最小的执行单位。

特征:
1、共享资源
2、效率高  30%
3、三方库: pthread  clone   posix
3.1 编写代码头文件: pthread.h
3.2 编译代码加载库: -lpthread   library 
libpthread.so
gcc 1.c -lpthread 
缺点:
1,线程和进程相比,稳定性,稍微差些
2,线程的调试gdb,相对麻烦些。

线程与进程的区别

资源:
线程比进程多了共享资源。  IPC
线程又具有部分私有资源。
进程间只有私有资源没有共享资源。
空间:
进程空间独立,不能直接通信。
线程可以共享空间,可以直接通信。

线程的创建

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);

功能:该函数可以创建指定的一个线程。
参数:thread 线程id,需要实现定义并由该函数返回。
attr   线程属性,一般是NULL,表示默认属性。
start_routine 指向指针函数的函数指针。
本质上是一个函数的名称即可。称为
th 回调函数,是线程的执行空间。

arg  回调函数的参数,即参数3的指针函数参数。
返回值:成功 0
失败 错误码

注意:一次pthread_create执行只能创建一个线程。
每个进程至少有一个线程称为主线程。
主线程退出则所有创建的子线程都退出。 
主线程必须有子线程同时运行才算多线程程序。
线程id是线程的唯一标识,是CPU维护的一组数字。多个子线程可以执行同一回调函数。

ps -eLf 查看线程相关信息Low Weigth Process
ps -eLo pid,ppid,lwp,stat,comm

pthread_t pthread_self(void); unsigned long int; %lu
功能:获取当前线程的线程id
参数:无
返回值:成功 返回当前线程的线程id
失败  -1;

线程的退出

1: 自行退出 ==》自杀  ==》子线程自己退出

void pthread_exit(void *retval);  exit  return p;
功能:子线程自行退出
参数: retval 线程退出时候的返回状态,临死遗言。
返回值:无

2: 强制退出 ==》他杀  ==》主线程结束子线程
int pthread_cancel(pthread_t thread);
功能:请求结束一个线程
参数:thread 请求结束一个线程tid
返回值:成功 0
失败 -1;

线程的回收

线程的回收机制 ====》不同与进程没有孤儿线程和僵尸线程。
====》主线程结束任意生成的子线程都会结束。
====》子线程的结束不会影响主线程的运行。

int pthread_join(pthread_t thread, void **retval);    
功能:通过该函数可以将指定的线程资源回收,该函数具有
阻塞等待功能,如果指定的线程没有结束,则回收线程
会阻塞。
参数:thread  要回收的子线程tid
retval  要回收的子线程返回值/状态。==》ptread_exit(值);
返回值:成功 0
失败 -1;

清理函数

void pthread_cleanup_push(void (*routine)(void *), void *arg);

功能:注册一个线程清理函数
参数,routine,线程清理函数的入口
arg,清理函数的参数。
返回值,无

void pthread_cleanup_pop(int execute);
功能:调用清理函数
execute,非0  执行清理函数
0 ,不执行清理

返回值,无
必须成对出现,他们本质属于带参宏,组合在一起构成do{}while;结构,不能分开。

子线程的回收策略:


1、如果预估子线程可以有限范围内结束则正常用pthread_join等待回收。
2、如果预估子线程可能休眠或者阻塞则等待一定时间后强制回收。
3、如果子线程已知必须长时间运行则,不再回收其资源。

线程函数的参数传递

传整数或者字符串

把要传的变量取地址放进pthread_create的参数部分

传结构体
1、定义结构体类型
2、用结构体定义变量
3、向pthread_create传结构体变量
4、从fun子线程中获取结构体数据

设置分离属性

设置分离属性后,目的线程消亡,自动回收空间。把回收的权限交给操作系统。

int pthread_deatch(pthread_t thread);
功能,设置分离属性
参数,线程id号,一般是在线程中调用,填自己的id

线程与进程的对照

process               thread 
fork                 pthread_create       创建
getpid,ppid         pthread_self        获取id号
exit,                  pthread_exit          自己主动退出
wait,waitpid,        pthread_join       空间回收
kill,                    pthread_cancel     被动退出
atexit                 pthread_clean,     注册清理函数
exec system--->fork->exec (ls)      进程可以在子进程中直接调用exec,但次线程需要先fork才能                                                           使用exec,不然其所在进程的代码会被全部替换     

一些注意事项

pthread_join(tid,?) ==>? = void **retval;
地址的地址
原理:子线程退出的时候,可以返回一个内存地址
改值所在的内存中可以存储任何数据,只要
地址存在,则数据都可以正常返回。

地址有三种:
0、栈区变量  错误,子线程结束该地址失效。
1、全局变量  失去意义,本质可以直接访问。

2、静态变量 
3、堆区变量


主线程通过一个地址形式的变量来接受子进程
返回的地址变量就可以将该地址中的数据取到。

http://www.dtcms.com/a/353017.html

相关文章:

  • 趣味学Rust基础篇(变量与可变性)
  • RCLAMP0504M.TBT电子元器件Semtech 低电容、四通道TVS二极管阵
  • Web漏洞
  • More Effective C++条款12:理解抛出一个异常与传递一个参数或调用一个虚函数间的差异
  • 火焰传感器讲解
  • 函数指针的简化
  • 毕业项目推荐:27-基于yolov8/yolov5/yolo11的电塔缺陷检测识别系统(Python+卷积神经网络)
  • MCP模型库深度解析:AI智能体工具调用生态的多元化与规模化发展
  • SciPy科学计算与应用:SciPy图像处理入门-掌握scipy.ndimage模块
  • 1 vs 10000:如何用AI智能体与自动化系统,重构传统销售客户管理上限?
  • 从高层 PyTorch 到中层 CUDA Kernel 到底层硬件 Tensor Core
  • fortran notes[2]
  • More Effective C++ 条款11:禁止异常流出析构函数之外
  • 自学嵌入式第二十九天:Linux系统编程-线程
  • 零后端、零配置:用 AI 编程工具「Cursor」15 分钟上线「Vue3 留言墙」
  • 从“找不到”到“秒上手”:金仓文档系统重构记
  • 深度学习-----详解MNIST手写数字数据集的神经网络实现过程
  • Linux系统使用ADB同时连接多个Android设备
  • 一、Mac(M1)本地通过docker安装Dify
  • 【Day 35】Linux-主从复制的维护
  • C语言中的static vs C++中的static:相同关键字,不同境界
  • golang13 单元测试
  • KingBase数据库迁移利器:KDTS工具 MySQL数据迁移到KingbaseES实战
  • uniapp中 ios端 scroll-view 组件内部子元素z-index失效问题
  • 大数据毕业设计选题推荐-基于大数据的城市空气污染数据分析系统-Spark-Hadoop-Bigdata
  • Elasticsearch三大属性详解:enabled、index与store
  • 【问题思考】为什么SVM中的w和超平面是垂直的?【SVM】【gemini生成】
  • Web转uni-app
  • 支持向量机(SVM)学习总结
  • 本地搭建 Redis/MySQL 并配置国内镜像加速(Docker/原生安装 | macOS/Linux/Windows)