1.共享内存
概述:共享内存是进程间最有用的通信方式,也是最快的IPC方式,同一块物理内存被映射到进程A、B各自的进程地址空间,多个进程共享一个内存区域,必然需要某种同步机制,互斥锁和信号量都可以。
在Linux下,通过ipcs -m 查看系统的共享内存
通过ipcrm -m xxxxx(shmid) 删除共享内存
原型:
共享内存:必须以兆(M)为单位 即size_t size = 1024*?
练习:进程write与read共享内存空间,write往内存空间写入数据,read读取数据并输出
注意:作为读取端read,无需创建共享内存,故将shmflag写0
2.信号
对于Linux,实际信号是软中断,许多重要的程序都需要程序处理信号,为Linux提供一种处理异步事件的方法,例如:终端用户输入crtl+c来中断程序,会通过信号机制停止程序。
概述:每个信号都有名字和编号,这些名字以"SIG"开头,例如:"SIGIO","SIGCHLD"等,通过指令 kill -l,查看信号的名字和序号,序号从1开始编号。
信号的处理:忽略、捕捉、默认
例如:又一个死循环程序,如何杀死该程序?
ps -aux|grep a.out //查看进程id kill -9 进程id 或 kill -SIGKILL 进程id
信号处理函数 信号发送函数
入门原型:
#include <signal.h>
typedef void (*sighandler_t)(int); //函数指针
sighandler_t signal(int signum, sighandler_t handler); //signum:信号(kill -l查看) handler:函数指针,指向函数名 //信号处理
int kill(pid_t pid, int sig);//信号发送
补充:sginal(SIGINT,SIG_IGN) //SIG_IGN忽略宏
练习:(1)信号处理函数:使用signal()函数,捕捉信号SIGXXX,当捕捉信号ctrl+c时,不会杀死进程
(2)信号发送函数:自己编写Mykill程序,杀死进程,通过调用kill()函数/system()函数,发送信号
信号处理:
信号发送:
高级原型://基于入门在发送与接收时携带数据
#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);//发信号
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);//收信号
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *); //复制该行编写处理函数handler,
sigset_t sa_mask; //阻塞标志,不配置默认阻塞
int sa_flags; //信号行为 :SA_SIGINFO(接收数据)
void (*sa_restorer)(void);
};//回调函数sa_handler和sa_sigaction只能任选其一
void handler(int signum, siginfo_t *info, void *context)
signum:信号序号 siginfo_t *info:结构体info void *context:指针:为空,无数据;非空,有数据
接收配置顺序:
(1)调用sigaction(信号名,结构体,NULL) //结构体对应struct sigaction,NULL表示不备份原操作(stop/kill等)
(2)声明结构体,配置结构体,
(3)编写处理函数handler
发送配置顺序:终端执行命令:执行文件 信号序号 进程ID
(1)定义signum信号,定义pid进程ID (2)使用atoi()函数,将输入的字符串ignum,pid转换为整型
(3)创建联合体value,设置发送数据的值 (4)调用siggueue(pid,signum,value)函数,发送数据
练习:使信号携带数据,一端发送,另一端接收
pro_signal.c
send_pro_signal.c
3.信号量
概述:信号量是一个计数器,用于进程间的互斥与同步,不是用于存储进程间的通信数据
特点:
(1)信号量用于进程间的同步,若要在进程间传递数据需要结合共享内存
(2)信号量是基于操作系统的PV操作
(3)支持信号量组
原型:
int num_sems:信号量集合中信号量的个数 int sem_flags:是否存在该信号量,没有创建,有则获取
int sem_num:信号量集合中第几个信号量(从0开始)
练习:编写信号量,父进程创建一个子进程,子进程进行v操作后,父进程进行p和v操作