一、进程间通信
进程间通信
1.管道、信号 //最早出现的两种方式
2.消息队列
共享内存
信号灯 //工程一般用的三种
3.套接字 //教育用的
本文列举1和2中的通信方式
1.管道
最简单的通信方式
管道分类
1.有名管道
2.无名管道
1.无名管道
管道是一段内核缓存区
只能用于具有亲缘关系的进程间通信
函数接口
pipe
int pipe(int pipefd[2]);
功能:
创建一个管道
参数:
pipefd[2]:一个两个元素的数组,用来存放读写文件描述符
返回值:
成功返回0
失败返回-1
2.管道特性
管道缓存区 64k
管道中至少有一个写端:
如果管道中有数据直接读取数据
如果管道中没有数据阻塞等待直到有数据写入再读出数据
管道中没有写端:
如果管道中有数据直接读取数据
如果管道中没有数据不阻塞等待直接继续向下执行
管道中至少有一个读端:
管道中数据没有写满,则直接写入数据
管道中数据已满,阻塞等待,等到有数据被读出才能继续写入
管道中没有读端:
管道中写入数据会产生管道破裂,进程异常结束
2.有名管道
函数接口
mkfifo
int mkfifo(const char *pathname, mode_t mode);
功能:
创建一个管道文件
参数:
pathname:管道文件路径
mode:管道文件权限
返回值:
成功返回0
失败返回-1
注意:
有名管道必须读写两端都加入后,才能继续向下执行
2.信号:
1.信号的种类
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47)SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
常用的几种:
SIGINT:ctrl + c
SIGQUIT:ctrl + \
SIGSEGV:段错误信号
SIGPIPE:管道破裂信号
SIGALRM:定时信号
SIGIO:异步IO
SIGTSTP:挂载信号 ctrl + z
SIGSTOP:暂停信号
SIGCONT:继续信号
SIGCHLD:子进程结束信号
以下信号不允许被忽略和捕捉:
9: SIGKILL
19: SIGSTOP
2.信号的处理方式
1.缺省
按照默认方式处理信号
2.忽略
不处理信号
3.捕捉
按照自定义方式处理信号
3.函数接口:
1.signal
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
功能:
设置信号的处理方法
1.缺省(按照默认方式处理信号)
2.忽略(不处理信号)
3.捕捉(按照handler对应的方式处理信号)
参数:
signum:信号的编号
handler:信号的处理方式
SIG_IGN 忽略
SIG_DFL 缺省
返回值:
成功返回之前处理信号的方式
失败返回SIG_ERR
2.pause
int pause(void);
功能:
让进程任务挂起
参数:
缺省
返回值:
成功任务挂起
被唤醒返回-1
3.alarm
unsigned int alarm(unsigned int seconds);
功能:
过seconds秒后,给进程发送SIGALRM信号
参数:
seconds:秒数
返回值:
返回上次定时剩余的秒数
4.kill
int kill(pid_t pid, int sig);
功能:
向pid对象的进程发送一个sig信号
参数:
pid:接收进程信号的ID
sig:信号的编号
返回值:
成功返回0
失败返回-1
3.消息队列:
IPC对象(内存文件)
生成key值 -> 创建消息队列 -> 发送/接收消息 -> 删除
1.查看所有IPC对象命令
ipcs
2.删除IPC对象命令
ipcrm
ipcrm -q/-m/-s msgid/shmid/semid 删除消息队列/共享内存/信号量数组(信号灯)
ipcrm -Q/-M/-S key
3.函数接口:
1.ftok
key_t ftok(const char *pathname, int proj_id);
功能:
根据pathname和proj_id生成一个IPC对象名字
参数:
pathname:路径
proj_id:项目ID(8位)
返回值:
成功返回key_t类型的IPC对象名
失败返回-1
2.msgget
int msgget(key_t key, int msgflg);
功能:
创建一个消息队列
参数:
key:键值
msgflg:
IPC_CREAT 没有就创建
IPC_EXCL 如果之前已经创建了消息队列,会报错
返回值:
成功返回消息队列的ID
失败返回-1
3.msgsnd
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:
向消息队列中发送消息
参数:
msqid:消息队列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号
msggp:存放接收到消息空间首地址
msgsz:接收消息的大小
msgtyp:消息队列的类型
msgflg:接收消息的标志 默认为0
返回值:
成功返回实际接收消息的字节数
失败返回-1
5.msgctl
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:
向消息队列发送一条命令
参数:
msqid:消息队列ID号
cmd:
IPC_STAT 获得消息队列属性
IPC_SET 设置消息队列权限
IPC_RMID 删除消息队列
buf:
根据命令传递内容不同
返回值:
成功返回0
失败返回-1
4.共享内存
进程间通信最高效
生成key值 -> 创建共享内存 -> 映射 -> 操作数据 -> 解除映射 -> 删除共享内存
函数接口:
1.shmget
int shmget(key_t key, size_t size, int shmflg);
功能:
创建一个共享内存空间
参数:
key:IPC对象名
size:共享内存空间大小
shmflg:
IPC_CREAT
IPC_EXECL
返回值:
成功返回共享内存ID
失败返回-1
2.shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:
将进程空间地址映射到共享内存
参数:
shmid:共享内存ID号
shmaddr:
NULL 系统选择一个合适的地址映射
返回值:
成功返回映射到共享内存空间中的地址
失败返回-1
3.shmdt
int shmdt(const void *shmaddr);
功能:
解除映射
参数:
shmaddr:共享内存空间的地址
返回值:
成功返回0
失败返回-1
4.shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:
向共享内存中发送一条命令
参数:
shmid:共享内存ID号
cmd:
IPC_STAT
IPC_SET
IPC_RMID 删除
buf:
NULL
返回值:
成功返回0
失败返回-1
5.信号量数组(信号灯)
也称有名信号量(线程中同步信号称无名信号量)
函数接口
1.ftok
2.semget
int semget(key_t key, int nsems, int semflg);
功能:
创建信号量数组
参数:
key:键值
nsems:信号量的个数
semflg:
IPC_CREAT
IPC_EXCL
返回值:
成功返回信号量ID
失败返回-1
3.semctl
int semctl(int semid, int semnum, int cmd, ...);
功能:
向信号量发送一条命令
参数:
semid:信号量的ID号
semnum:信号量的编号
cmd:
IPC_SET
IPC_STAT
IPC_RMID
SETVAL 设置初值
返回值:
成功返回0
失败返回-1
4.semop
int semop(int semid, struct sembuf *sops, size_t nsops);
功能:
申请和释放信号量
参数:
semid:信号量的ID号
sops:申请释放操作信号量的数组空间首地址
nsops:对信号量操作的数组长度
返回值:
成功返回0
失败返回-1
struct sembuf内容
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
附加
(消息队列+共享内存+信号灯) 都可在ipcs查看