LV.5 进程、线程和进程间通信
2022-01-22 14:13:42 0 举报
AI智能生成
进程、线程和进程间通信
作者其他创作
大纲/内容
D1 进程的创建和回收
进程概念
概念
程序
存放在磁盘上的指令和数据的有序集合(文件)
静态的
进程
执行一个程序所分配的资源的总称
进程是程序的一次执行过程
动态的,包括创建、调度、执行和消亡
进程内容
内容
进程控制块
进程控制块(pcb)
进程标识PID
进程用户
进程状态、优先级
文件描述符表
进程类型
交互进程
交互进程:在shell下启动。以在前台运行,也可以在后台运行
批处理进程
批处理进程:和在终端无关,被提交到一个作业队列中以便顺序执行
守护进程
守护进程:和终端无关,一直在后台运行
进程状态
运行态:进程正在运行,或者准备运行
停止态:进程被中止,收到信号后可继续运行
死亡态:已终止的进程,但pcb没有被释放
进程状态图
进程常用命令
查看进程信息
ps
查看系统进程快照
top
查看进程动态信息
/proc
查看进程详细信息
进程相关命令
nice
按用户指定的优先级运行进程
renice
改变正在运行进程的优先级
jobs
查看后台进程
bg
将挂起的进程在后台运行
fg
把后台运行的进程放到前台运行
创建子进程
子进程概念
子进程为由另外一个进程(对应称之为父进程)所创建的进程
子进程创建
fork
示例
父子进程
子进程继承了父进程的内容
父子进程有独立的地址空间,互不影响
若父进程先结束 1.子进程成为孤儿进程,被init进程收养 2.子进程变成后台进程
若子进程先结束:父进程如果没有及时回收,子进程变成僵尸进程
思考
例题:通过父进程创建5个子进程
参考代码
进程的退出
进程结束
exit/_exit
示例
进程的回收
进程回收
概念
子进程结束时由父进程回收
孤儿进程由init进程回收
若没有及时回收会出现僵尸进程
wait/waitpid
示例
进程返回值和结束方式
D2 exec函数族和守护进程
exec函数族
概念
进程调用exec函数族执行某个程序
进程当前内容被指定的程序替换
实现让父子进程执行不同的程序
流程
execl/execlp
示例
execv/execvp
示例
system
守护进程概念
简介
守护进程(Daemon Process)是Linux三种进程类型之一
是 Linux 中的后台服务进程
是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件
特点
始终在后台运行
独立于任何终端
周期性的执行某种任务或等待处理特定事件
相关概念
进程组(Process Group): 进程集合,每个进程组有一个组长(Leader),其进程 ID 就是该进程组 ID。
会话(Session): 进程组集合,每个会话有一个组长,其进程 ID 就是该会话组 ID。
控制终端(Controlling Terminal):每个会话可以有一个单独的控制终端,与控制终端连接的 Leader 就是控制进程(Controlling Process)。
守护进程的创建
1. 创建子进程,父进程退出
2. 子进程创建新会话
3. 更改当前工作目录
4. 重设文件权限掩码
5. 关闭打开的文件描述符
守护进程的实现
示例:创建守护进程,每隔1秒将系统时间写入文件time.log
GDB调试多进程程序
D3 线程的创建和回收
线程的创建
进程概念
进程有独立的地址空间
Linux为每个进程创建task_struct
每个进程都参与内核调度,互不影响
线程概念
进程在切换时系统开销大
很多操作系统引入了轻量级进程LWP
同一进程中的线程共享相同地址空间
Linux不区分进程、线程
线程特点
通常线程指的是共享相同地址空间的多个任务
使用多线程的好处:1.大大提高了任务切换的效率 2.避免了额外的TLB & cache的刷新
线程共享资源
可执行的指令
静态数据
进程中打开的文件描述符
当前工作目录
用户ID
用户组ID
线程私有资源
线程ID (TID)
PC(程序计数器)和相关寄存器
堆栈
错误号 (errno)
优先级
执行状态和属性
Linux线程库
基本操作
创建线程
回收线程
结束线程
同步互斥机制
信号量
互斥锁
线程创建
pthread_create
示例
线程结束
pthread_exit
线程查看
pthread_self
线程查看命令
ps -eLf
线程的参数传递
pthread_reate
示例
示例2
线程的回收
线程回收
pthread_join
示例
线程分离
pthread_detach
示例1
示例2
线程回收内存演示
示例
D4 线程的取消和互斥
线程的取消
pthread_cancel
示例
线程的清理
pthread_cleanup_push/pthread_cleanup_pop
示例
互斥锁的概念和使用
互斥概念
临界资源
一次只允许一个任务(进程、线程)访问的共享资源
临界区
访问临界资源的代码
互斥机制
mutex互斥锁:任务访问临界资源前申请锁,访问完后释放锁
互斥锁的使用
方法
初始化(创建)
动态方式
pthread_mutex_init
静态方式
PTHREAD_MUTEX_INITALIZER
申请
pthread_mutex_lock/pthread_mutex_trylock
释放
pthread_mutex_unlock
销毁
pthread_mutex_destroy
示例
读写锁概念和使用
概念
使用
示例
死锁的避免
示例
D5 条件变量和进程池
条件变量
应用场景
生产者消费者问题,是线程同步的一种手段
必要性
为了实现等待某个资源,让线程休眠。提高运行效率
方法
pthread_cond_init
pthread_cond_wait
pthred_cond_timedwait
pthread_cond_signal
pthread_cond_broadcast
pthread_cond_destroy
使用步骤
初始化
静态初始化
动态初始化
生产资源线程
开始产生资源
消费者线程
示例
出租车模型
线程池
概念
通俗的讲就是一个线程的池子,可以循环的完成任务的一组线程集合
必要性
线程池的基本结构
任务队列,存储需要处理的任务,由工作线程来处理这些任务
线程池工作线程,它是任务队列任务的消费者,等待新任务的信号
线程池的实现
1. 创建线程池的基本结构
2. 线程池的初始化
3. 线程池添加任务
4. 实现工作线程
5. 线程池的销毁
示例代码
D6 有名管道和无名管道
进程间通讯介绍
无名管道(pipe)
有名管道(fifo)
信号(signal)
共享内存(mmap)
套接字(socket)
System V IPC
共享内存(share memory)
消息队列(message quiui)
信号灯集(semaphore set)
无名管道基础
介绍
图解
特点
只能用于具有亲缘关系的进程之间的通信
单工的通信模式,具有固定的读端和写端
无名管道创建时会返回两个文件描述符,分别用于读写管道
功能
无名管道创建
pipe
通讯图解
注意事项
读写特性
读管道
写管道
示例1
示例2
示例3
有名管道
创建
特点
注意事项
示例
D7 共享内存
共享内存
概念
内存映射概念
mmap的优点
实现了用户空间和内核空间的高效交互方式
提供方法
mmap
注意事项
示例:基本使用
示例:匿名映射
system V IPC 共享内存
System V IPC 介绍
IPC对象包含:共享内存、消息队列和信号灯集
每个IPC对象有唯一的ID用Key关联
IPC对象创建后一直存在,直到被显式的删除
ipcs / ipcrm
共享内存特点
共享内存是一种最为高效的进程间通信方式, 进程可共享内存是一种最为高效的进程间通信方式,进程可
以直接读写内存,而不需要任何数据的拷贝以直接读写内存,而不需要任何数据的拷贝
以直接读写内存,而不需要任何数据的拷贝以直接读写内存,而不需要任何数据的拷贝
共享内存在内核空间创建,可被进程映射到用户空间共享内存在内核空间创建,可被进程映射到用户空间
访问,使用灵活访问,使用灵活
访问,使用灵活访问,使用灵活
由于多个进程可同时访问共享内存,因此需要同步和由于多个进程可同时访问共享内存,因此需要同步和
互斥机制配合使用互斥机制配合使用
互斥机制配合使用互斥机制配合使用
使用步骤
1. 生成Key
示例
2. 创建/打开共享内存
3. 映射共享内存
4. 读写共享内存
5. 撤销共享内存映射
6. 删除共享内存对象
注意事项
每块共享内存有大小限制
共享内存删除的时间点
应用:进程间通讯
D8 信号机制
概念
信号机制
信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
linux内核通过信号通知用户进程,不同的信号类型代表不同的事件
Linux对早期的unix信号机制进行了扩展
进程对信号的响应方式
缺省方式
忽略信号
捕捉信号
信号的产生
按键产生
系统调用函数产生(比如raise, kill)
硬件异常
命令行产生 (kill)
软件条件(比如被0除,访问非法内存等)
常用信号1
SIGHUP
SIGINT
SIGQUIT
SIGILL
SIGSEV
SIGPIPE
常用信号2
SIGKILL
SIGSTOP
SIGTSTP
SIGCONT
SIGALRM
SIGUSR1/2
信号相关命令
kill / killall
相关函数
信号发送函数
raise / kill
示例
定时器函数
alarm / pause
示例
其他定时器函数
ualarm/setitimer
信号的捕捉
概念
图解
信号捕捉过程
1. 定义新的信号的执行函数handle
2. 使用signal/sigaction 函数,把自定义的handle和指定的信号相关联
相关函数
signal
示例
sigaction
示例
setitimer
示例
SIGCHLD信号的使用
概述
产生条件
子进程终止时
子进程接收到SIGSTOP信号停止时
子进程处在停止态,接受到SIGCONT后唤醒时
功能
可以用来处理子进程退出的僵尸
示例
信号集、信号的阻塞
简介
有时候不希望在接到信号时就立即停止当前执行,去处理信号,同时也不希望忽略该信号,而是延时一段时间去调用信号处理函数。这种情况可以通过阻塞信号实现。
概念
信号的阻塞
信号的”阻塞“是一个开关动作,指的是阻止信号被处理,但不是阻止信号产生。
信号的状态
信号递达(Delivery ):实际信号执行的处理过程(3种状态:忽略,执行默认动作,捕获)
信号未决(Pending):从产生到递达之间的状态
图解
信号集操作函数
set
sigset_t set; 自定义信号集。 是一个32bit 64bit 128bit的数组
sigemptyset
sigemptyset(sigset_t *set); 清空信号集
sigfillset
sigfillset(sigset_t *set); 全部置1
sigaddset
sigaddset(sigset_t *set, int signum); 将一个信号添加到集合中
sigdelset
sigdelset(sigset_t *set, int signum); 将一个信号从集合中移除
sigismember
sigismember(const sigset_t *set,int signum); 判断一个信号是否在集合中。
sigprocmask
设定对信号集内的信号的处理方式(阻塞或不阻塞)
示例
信号驱动任务
函数
pause
sigsuspend
D9 消息队列和信号灯
消息队列
概念
消息队列是System V IPC对象的一种
消息队列由消息队列ID来唯一标识
消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等
消息队列可以按照类型来发送/接收消息
消息队列结构
使用步骤
1. 打开/创建消息队列
msgget
2. 向消息队列发送消息
msgsnd
3. 从消息队列接收消息
msgrcv
4. 控制消息队列
msgctl
信号灯概念和有名信号灯
概念
信号灯/量(semaphore)
信号量代表某一类资源, 其值表示系统中该资源的数量
信号量是一个受保护的变量, 只能通过三种操作来访问
初始化
P操作(申请资源)
V操作(释放资源)
伪代码
三种信号灯
Posix 有名信号灯
Posix 无名信号灯
System V 信号灯
有名信号灯的使用
打开
sem_open
P操作
sem_wait
V操作
sem_post
关闭
sem_close
删除
sem_unlink
无名信号灯的使用
打开
sem_init
P操作
sem_wait
V操作
sem_post
删除
sem_destory
System V 信号灯的使用
创建/打开
semget
P/V操作
semop
初始化/删除
semctl
0 条评论
下一页