Linux系统编程4 线程编程


主要内容:

  1. 线程概念
  2. 基本API函数
  3. 线程同步
  4. 线程属性

线程概念

—一个进程创建的多个线程共享进程的地址空间。
—创建子进程是复制的父进程的地址空间(进程与进程间是独立的)
—同一程序中的所有线程都会执行相同的程序,且共享内存的内存段,包括数据段,堆区。(进程的栈区对线程不共享,每个线程都拥有属于自己的栈区)
—线程间的通信是通过操作共享的数据段实现的。(而进程所操作的地址空间都是独立的,因此进程之间的通信要引入进程的通信机制来实现。)

*Linux中引入同步互斥机制,从而保证某一个线程在操作共享资源时,不会被其他线程打扰。(即某一时刻,只有一个线程在对共享资源进行访问。)
在这里插入图片描述
在这里插入图片描述
ps axm(Linux可以看到进程的详细信息,可以看到–标识,就是线程)
ps ax -L(以Linux的形式查看进程和线程的关系)

基本API函数

1. pthread_create函数

在这里插入图片描述
pthread_create用于在进程中创建一个线程。
在这里插入图片描述
线程可用pthread_self来获取自己的ID。

2. pthread_exit函数

在这里插入图片描述

线程的退出方式:
(1)线程的执行函数执行return语句并返回指定值。
(2)线程调用pthread_exit()函数。
(3)调用pthread_cancel()函数取消线程。
(4)任意线程调用exit()函数,或者main()函数中执行了return语句,都会造成进程中的所有线程立即终止。在这里插入图片描述
若一个线程调用了pthread_exit()函数,但其他进程仍然继续执行。
在这里插入图片描述

3. pthread_cancel函数

pthread_cancel()函数向由 tid 指定的线程发送一个取消请求。发送取消请求后,函数pthread_cancel()立即返回,不会等待目标线程的退出。
在这里插入图片描述

4. 线程回收 pthread_join函数

若进程并未进行分离,则必须要用pthread_join函数来进行回收资源。
在这里插入图片描述
在这里插入图片描述

线程同步

—线程间的通信访问了共享的进程数据段中的全局变量,(即并发的线程访问了相同的资源,所以造成了数据的不确定性),因此线程的通信要结合一些同步互斥机制一起使用。

1. 线程同步的概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 线程互斥锁

线程加锁成功,则可以访问共享资源,期间不会被打断,在访问结束之后解锁
—先持有锁的进程先访问,其他进程只能阻塞等待。
—互斥锁并不能保证线程的执行先后,却可以保证对共享资源操作的完整性。
在这里插入图片描述

互斥锁的使用:
初始化互斥锁 互斥锁上锁 互斥锁解锁 互斥锁释放
在这里插入图片描述

2.1 线程互斥锁初始化

在这里插入图片描述

2.2 线程互斥锁销毁(释放)

只有当互斥锁处于未锁定状态,讲其摧毁才安全。
在这里插入图片描述

2.3 线程互斥锁加锁和解锁

初始化之后,互斥锁处于未锁定状态。
在这里插入图片描述
如果该锁资源处于持有状态,那么调用此函数将会直接导致线程阻塞。

2.4 尝试锁

在这里插入图片描述

2.5 互斥锁的操作顺序

在这里插入图片描述

2.6. 互斥锁 死锁

在这里插入图片描述

3. 条件变量

在这里插入图片描述
条件变量需要结合互斥锁一起使用。

条件变量:让当前不需要访问共享资源的线程进程阻塞等待(睡眠),如果某一时刻需要某一个线程处理,那么则可以将该线程进行唤醒。

条件变量也需要初始化 其核心操作是阻塞线程及唤醒进程,最后将其摧毁。
在这里插入图片描述

3.1 条件变量函数

在这里插入图片描述
条件变量初始化:
在这里插入图片描述
条件变量摧毁:
在这里插入图片描述
条件变量阻塞等待:
在这里插入图片描述
条件变量唤醒:
在这里插入图片描述

4. 信号量

在这里插入图片描述

信号量的工作原理:
—所有对共享资源操作的线程,在访问共享资源之前,都需要先操作信号量的值(即PV操作)。
P为申请信号量(-1),V为释放信号量(+1)。
当信号量的值为0时,申请信号量时将会阻塞,其值不能减为负数。
信号量:实现互斥时,多线程只需设置一个信号量;
实现同步时,需要设置多个信号量。

4.1 信号量的初始化

在这里插入图片描述

4.2 其他函数

在这里插入图片描述
P : sem_wait()用来申请信号量,申请成功,信号量的值减1。(当信号量的值为0时,此操作将会阻塞,直到其他线程执行释放信号量)。
sem_trywait()函数不会阻塞,当信号量为0时,函数直接返回错误码EAGAIN.
V : sem_post()函数用来释放信号量,释放成功,信号量的值加1。
sem_getvalue()函数用来获取当前信号量的值,并保存在参数sval中。
sem_destroy()函数用来摧毁信号量。
—sem : 表示信号量的标识符。

线程属性

在这里插入图片描述
创建线程的函数中,attr参数可设置线程的属性。
attr设置为NULL,则线程为默认属性。
在这里插入图片描述

1. 线程属性初始化和销毁

在这里插入图片描述

2. 线程的分离状态

在这里插入图片描述
一旦线程处于分离状态,就不能再使用pthread_join()函数来获取其状态。

2.1 设置线程分离状态方法1

----线程分离,也可以在线程刚一创建的时候就进行分离,(而不是之后再调用pthread_detach()函数)
----步骤:
1.采用默认方式对线程属性结构进行初始化。(pthread_attr_init)
2.为创建分离进程设置属性。(pthread_attr_setdetachstate)
3. 以此线程属性结构来创建新进程。(pthread_create)
4. 摧毁该线程属性结构。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 设置线程分离方法2

在这里插入图片描述

3. 线程的取消

设置取消线程属性
向一个线程发送一个请求,要求其立即退出。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值