1.信号:
实现用户层和内核层通信
1.信号的分类
kill -l
每种信号都具有固定含义
2.常用信号:
SIGINT:打断进程任务 可以从终端输入(ctrl + c)
SIGQUIT:让进程任务退出 可以从终端输入(ctrl + \)
SIGTSTP:然进程任务挂起 可以从终端输入(ctrl + z)
SIGSEGV:内存操作错误
SIGBUS:总线错误
SIGABRT:程序异常
SIGPIPE:管道破裂
SIGCHLD:有子进程结束
SIGSTOP:暂停进程任务
SIGCONT:让暂停任务继续执行
SIGIO:异步IO信号
SIGKILL:让进程结束
3.应用层处理信号的方式:
1.缺省
按照默认方式处理信号
2.忽略
不处理信号
3.捕捉
按照自定义的方式处理信号
注意:
SIGKILL(9) SIGSTOP(19) 不能被忽略和捕捉
4.函数接口:
1.signal
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
功能:
注册一个信号的处理方式(缺省、忽略和捕捉)
参数:
signum:信号的编号
handler:
SIG_IGN 忽略
SIG_DFL 缺省
信号处理函数首地址
返回值:
成功返回上一次的信号处理函数
失败返回SIG_ERR
void (*signal(int signum, void (*handler)(int)))(int);
练习:程序间隔1s打印,"程序正在执行"
按下 ctrl + c 打印 "SIGINT信号来了"
按下 ctrl + \ 打印 "SIGQUIT信号来了"
按下 ctrl + z 打印 "SIGTSTP信号来了"
2.pause
int pause(void);
功能:
让进程/线程任务挂起
3.raise
int raise(int sig);
功能:
向调用该函数的任务发送信号
4.alarm
unsigned int alarm(unsigned int seconds);
功能:
定时seconds秒后给自己发送一个SIGALRM信号
5.kill
int kill(pid_t pid, int sig);
功能:
给进程发送信号
参数:
pid:进程的ID号
sig:信号的编号
返回值:
成功返回0
失败返回-1
3.消息队列:
1.IPC对象:内存文件
2.操作命令:
1.ipcs
查看所有的IPC对象
-m 查看共享内存
-q 查看消息队列
-s 查看信号量数组(信号灯)
2.ipcrm
删除指定IPC对象
ipcrm -m/q/s key(IPC对象名称)
ipcrm -M/Q/S id(共享内存/消息队列/信号灯ID)
3.操作方式:
1.创建IPC对象的名称
2.创建消息队列
3.向消息队列中发送消息
4.可以从消息队列中接收消息
5.消息队列删除
4.函数接口:
1.ftok
key_t ftok(const char *pathname, int proj_id);
功能:
根据路径和proj_id生成IPC对象名称
参数:
pathname:路径
proj_id:8bits项目ID,不能为0
返回值:
成功返回IPC对象名称
失败返回-1
2.msgget
int msgget(key_t key, int msgflg);
功能:
创建一个消息队列
参数:
key:IPC对象名称
msgflg:
IPC_CREAT 如果不存在就创建
IPC_EXCL 如果存在报错
返回值:
成功返回消息队列的ID号
失败返回-1
3.msgsnd
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:
向消息队列中发送消息
参数:
msgqid:消息队列的ID号
msgp:发送消息空间的首地址
msgsz:发送消息的大小
msgflg:发送消息属性,默认为0
返回值:
成功返回0
失败返回-1
4.msgrcv
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
功能:
从消息队列中接收消息
参数:
msqid:消息队列的ID号
msgp:存放接收到信息空间的首地址
msgsz:最大接收消息的大小
msgtyp:接收消息的类型
msgflg:接收消息属性,默认为0
返回值:
成功返回实际接收到内容的大小(不包含类型)
失败返回-1
5.msgctl
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:
向消息队列发送命令
参数:
msqid:消息队列的ID号
cmd:
IPC_RMID 删除
buf:
传递NULL
返回值:
成功返回0
失败返回-1
作业:
1.1014 福尔摩斯的约会
https://pintia.cn/problem-sets/994805260223102976/exam/problems/994805308755394560?type=7&page=0
2.使用消息队列实现两个进程间的通信
1.clientA.c clientB.c 交替收发
2.全双工通信