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

Linux软件编程--线程

1、基本概念

  • 线程:线程是操作系统中的基本执行单元,也是程序执行流的最小单位
  • 线程是轻量级的进程(本质上是一个进程,但进程与线程的空间管理方式不同)
  • 线程是 CPU 任务调度的最小单元
  • 进程是操作系统资源分配的最小单元

2、线程空间

  • 线程必须位于进程中,没有进程,线程无法单独存在
  • 线程共享文本段、数据段、堆区空间,独享栈区空间
  • 一个进程中的线程切换调度任务是,资源开销较小

3、多线程与多进程的对比

场景多进程多线程
效率多进程需要切换映射的物理地址,资源开销较大多线程在同一进程空间内切换任务,资源开销较小
通信多进程间内存不共享,需要通过进程间通信的方法通信多线程间共享空间,只需要改变共享空间的数据就能完成通信
资源竞争多进程之间没有共享空间,不存在资源竞争多线程通过共享空间通信,需保证资源使用的互斥性,防止线程之间的资源竞争
安全多进程间空间独立,一个程序崩溃不会影响其他进程,相对较安全多线程间空间共享,一个程序崩溃会影响其他线程运行

4、线程的调度与消亡

        与进程的调度与消亡保持一致

5、线程的函数接口

  1.线程创建接口

        pthread_create

原型:

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

功能:

        在进程中创建一个线程

参数:

        thread:存放线程 ID 的首地址

        attr:线程的属性,默认为 NULL

        start_routine:线程函数的入口

        arg :线程函数的参数

  2.线程 ID 获取接口

        pthread_self 

原型:

        pthread_t pthread_self(void);

功能:

        获得调用该函数的线程的ID号

  3.线程退出接口

        pthread_exit

原型:

        void pthread_exit(void *retval);

功能:

        结束当前线程任务

参数:

        retval:线程结束的值

4.回收线程接口

        pthread_join

原型:

        int pthread_join(pthread_t thread, void **retval);

功能:

        回收线程空间

参数:

        thread:要回收的线程的ID

        retval:存放线程结束状态空间的首地址

返回值: 成功返回0 失败返回错误码

6、线程属性

  1.概念:
  • 加入属性:线程结束后需要通过 pthread_join 手动回收线程空间
  • 分离属性:线程结束后程序自动回收线程空间
  2.相关函数接口

        初始化函数接口:pthread_attr_init

原型:

        int pthread_attr_init(pthread_attr_t *attr);

功能:

        线程属性初始化

参数:

        attr:初始化线程首地址

        属性设置接口:pthread_attr_setdetachstate

原型:

        int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

功能:

        设置线程属性

参数:

        attr :线程属性空间首地址

        detachstate:属性设置

                PTHREAD_CREATE_DETACHED:分离属性

                PTHREAD_CREATE_JOINABLE:加入属性

        销毁线程属性对象接口:pthread_attr_destroy

原型:

  •         int pthread_attr_destroy(pthread_attr_t *attr);

功能:

        线程属性销毁

参数:

        attr:线程属性空间首地址

7、线程间通信

  • 采用全局变量实现进程间通信
  • 多线程同时操作会引发资源竞争,需加上互斥锁解决资源竞争问题

8、互斥锁

  1.概念与特点
  • 解决资源竞争的一种方式也可以看成是一种资源
  • 只能加锁一次,在加锁期间不能再次加锁,也不能羌之战有一个加锁的资源,必须等待资源释放(解锁后操作)
  • 只能防止线程之间的资源竞争,不能改变代码的先后执行顺序
  2.使用方式
  • 定义互斥锁(全局变量)并对锁初始化
  • 操作全局资源前先加锁,如果加锁成功则完成对全局资源操作
  • 如果加锁失败则表示有人占用资源,必须等待其余人释放锁资源才能加锁成功
  3.相关函数接口
        互斥锁初始化函数

        pthread_mutex_init

原型:

        int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

功能:

        初始化互斥锁

参数:

        mutex:互斥锁空间首地址

        attr:互斥锁属性,默认为 NULL

返回值:

        成功0,失败-1

         互斥锁加锁与开锁与销毁

         pthread_mutex_lock  /   pthread_mutex_unlock  /pthread_mutex_destroy

加锁函数:

原型:

        int pthread_mutex_lock(pthread_mutex_t *mutex);

开锁函数:

原型:

        int pthread_mutex_unlock(pthread_mutex_t *mutex);

销毁函数:

原型:

        int pthread_mutex_destroy(pthread_mutex_t *mutex);

  9、死锁

  1.概念

        两个或两个以上的线程(或进程)在执行过程中,由于竞争资源或彼此通信而造成的一种互相等待的现象

  2.死锁的特点
  • 没有外部干预时,这种等待状态将永久持续
  • 每个线程/进程都在等待其他线程/进程释放资源
  3.死锁的产生条件
  • 互斥条件:资源一次只能被一个线程占用(若资源可以被共享访问,则不会产生死锁)
  • 占有并等待:线程至少占有一个资源的同时又等待获取其他线程的资源
  • 不可剥夺:已经分配给现成的资源不能被其他线程强行夺取
  • 循环等待:存在一个线程等待环路

10、信号量

  1.概念
  • 信号量是一种用于多线程/多进程环境下控制共享资源访问的同步机制
  • 信号量只能完成初始化、销毁、申请、释放四种操作
  2.函数接口
        初始化函数:sem_init

原型:

        int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:

        初始化信号量

参数:

        sem:信号空间首地址

        pshared:进程共享开关

                0:一个进程间的多个线程共享

                非0:多个进程间共享

        value:初始化资源的值

                如哦资源职位0,申请资源会阻塞等待,直到占用资源的任务释放资源,资源部为                  0 才能申请到资源并向下执行

返回值:

        成功 0,失败 -1 

        销毁信号量函数:sem_destroy

原型:

        int sem_destroy(sem_t *sem);

功能:

        销毁信号量

返回值:

        成功 0,失败 -1

        信号量申请函数:sem_wait
  • 申请信号量会让信号量资源数 -1
  • 若信号量资源数为 0,会阻塞等待直到有任务释放资源

原型:

        int sem_wait(sem_t *sem);

功能:

        申请信号量

参数:

        sem:信号量空间首地址

返回值:

        成功返回0 失败返回-1

        信号量释放函数:sem_post
  • 信号量释放后 信号量资源 +1

原型:

        int sem_post(sem_t *sem);

功能:

        释放信号量

参数:

        sem:信号量空间首地址

返回值:

        成功返回0 失败返回-1

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

相关文章:

  • 蓝牙音频ANC四通道测试解决方案
  • 新经济形态下人才能力结构变革与发展研究报告
  • Win10快速安装.NET3.5
  • RecSys:多目标模型和MMOE
  • .NET8下的Garnet使用
  • androidstudio内存大小配置
  • 研究生第十六周周报
  • 718SJBH公交查询系统
  • 4.6 Vue 3 中的模板引用 (Template Refs)
  • Sklearn 机器学习 邮件文本分类 加载邮件数据
  • [Responsive theme color] 动态主题 | 色彩工具函数 | HEX与RGB
  • 嵌入式第三十天(线程)
  • 围棋对战游戏开发详解 附源码
  • 【C++】标准库中用于组合多个值的数据结构pair、tuple、array...
  • k8s+kubeedge的混合框架下,云端pod与边缘端pod如何进行通信?
  • HTTP协议-1-认识各个HTTP协议版本的主要特点
  • Python进行点云公共区域的提取
  • Docker目录的迁移
  • 银行间交易IMIX协议加密相关
  • 后台管理系统-4-vue3之pinia实现导航栏按钮控制左侧菜单栏的伸缩
  • 机器学习——线性回归
  • 平滑方法(smoothing)
  • Python-深度学习——pytorch的安装
  • 开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
  • VSCode匹配删除多行注释
  • JavaScript 核心语法与实战笔记:从基础到面试高频题
  • 从“Hello World”到“高并发中间件”:Go 语言 2025 系统学习路线图
  • 深入解析C++ STL链表(List)模拟实现
  • 微服务之注册中心与ShardingSphere关于分库分表的那些事
  • 类与类加载器