一、信号管理
1、函数signal
signal函数是UNIX系统信号机制最简单的接口
#include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler ); /* signum:信号的编号 handler: 函数指针 接到此信号时要调用的程序 SIG_IGN 忽略signum信号 SIG_DFL 恢复信号默认的处理方式 返回值:信号设置之前信号的处理方式 函数指针、SIG_IGN、SIG_DFL */
该函数用于设置一个指定信号的处理方式,可以一个自定义的指定类型函数,也可以选择忽略信号或恢复信号默认处理方式
2、函数kill
#include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); // 功能:向指定的进程发送信号 // pid:与waitpid一样 // sig:信号码 // 0 空信号,不会向进程发送信号,但是会测试是否能向pid发送信号,可以检测一个进程是否存在,返回-1 表示进程不存在,errno变为ESRCH。 // 返回值:-1 说明进程不存在
该函数用于进程之间发送信号,可以在进程间通信使用共享内存时,用于发送读完毕或写完毕信号避免多进程同时访问同一块内存造成错误
二、进程间通信
1、共享内存
1、由内核维护一块共享的内存区域,其它进程,把自己的虚拟地址映射到这块内存,多个进程之间就可以共享这块内存了。
2、这种进程间通信的好处是不需要信息复制,它是进程间通信最快的一种方式。
3、但这种通信方式会面临同步的问题,需要与其它通信方式配合,最合适的就是信号。
进程之间互相约定一个key值,此key值将会作为内核定位同一块内存的依据,使得多个进程之间能够共享一块内存
#include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> int shmget(key_t key, size_t size, int shmflg);/* 功能:创建共享内存 size:共享的大小 shmflg:IPC_CREAT:创建 IPC_EXCL :如果存在创建失败 IPC_EXCL | IPC_CREAT mode_flags 权限 返回值:IPC对象标识符(类似文件描述符) shmget(key,size,0744|IPC_CREAT);*/ void *shmat(int shmid, const void *shmaddr, int shmflg); /* 功能:加载共享内存(进程的虚拟地址和共享的内存进行映射) shmid:shmget的返回值 shmaddr:进程提供的虚拟地址,如果为 NULL 操作系统会自动选择一块地址映射 shmflg: SHM_RDONLY: 限制内存的权限为只读 SHM_REMAP: 映射已经存在的共享内存 SHM_RND: 当shmaddr为NULL时自动分配 SHMLBA : shmaddr值不能为空,否则出错 返回值:映射后的虚拟地址 */ int shmdt(const void *shmaddr);/* 功能:卸载共享内存(进程的虚拟地址与共享内存取消映射关系)*/ int shmctl(int shmid, int cmd, struct shmid_ds *buf);/* 共享:控制/销毁共享内存 cmd: IPC_STAT:获取共享内存的属性 IPC_SET :设置共享内存的属性 IPC_RMID:删除共享内存 buf:记录共享内存属性的对象*/
共享内存一旦创建,系统上的进程只要拥有它的key值就能够通过函数shmget,shmat访问到该内存。
共享内存操作麻烦,需要配合信号使用,但共享内存更适合于较大的数据通信。
1、消息队列
1、消息队列是一个由系统内核负责存储和管理、并通过IPC对象标识符获取的数据链表。
2、使用消息队列需要创建一个定义了消息类型和消息大小的结构体,例:
struct msgbuf { long mtype; /*消息的类型,必须大于0 */ char mtext[255]; /* 传输的数据 */ };
以下几个是于消息队列有关的函数:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgget(key_t key, int msgflg);/* 功能:创建或获取消息队列 msgflg: 创建时 IPC_CREAT | IPC_EXCL | 0751(权限) 获取时 0 */ int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);/* 功能:向消息队列发送消息 msqid:msgget的返回值 msgp: 消息(消息类型+消息的内容)的首地址,如上的结构体 msgsz:消息内容的长度(不包括消息类型) msgflg: MSG_NOERROR: 当消息的实际长度比msgsz还要大,不产生错误,把消息按照长度截取发送*/ ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);/* 功能:从消息队列接收消息 msgp:存储消息的缓冲区 msgsz:要接收的消息长度 msgtyp:消息的类型(它包含在消息的前四个字节) msgflg IPC_NOWAIT:如果要接收的消息不存在,则不等待 MSG_EXCEPT:从消息队列中接收第一个不是msgtype类型的第一个消息。*/ int msgctl(int msqid, int cmd, struct msqid_ds *buf);/* 功能:控制/销毁消息队列 cmd: IPC_STAT:获取消息队列的属性 IPC_SET:设置消息队列的属性 IPC_RMID:删除消息队列*/