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