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

相关推荐
一只栖枝2 分钟前
华为 HCIE 大数据认证中 Linux 命令行的运用及价值
大数据·linux·运维·华为·华为认证·hcie·it
fouryears_2341733 分钟前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
我好喜欢你~1 小时前
C#---StopWatch类
开发语言·c#
wuicer2 小时前
ubuntu 20.04 安装anaconda以及安装spyder
linux·运维·ubuntu
lifallen2 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研2 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
小狗爱吃黄桃罐头4 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
鱼鱼说测试4 小时前
Jenkins+Python自动化持续集成详细教程
开发语言·servlet·php
小晶晶京京4 小时前
day34-LNMP详解
linux·运维·服务器