信号通信:
异步通信: 当我们关注某一个事件时,如果事件未发生,我们继续完成自己任务, 当事件发生后,它会给我们传递一个信号,此时我们再回头完成对应事件 信号处理方式: 捕捉:信号发生后,我们通过某些方法(函数)获取对应信号然后自定义该信号的处理方式
忽略:信号不在执行对应的默认操作(SIGKILL/SIGSTOP除外)
默认:
kill指令: kill -n pid: 给pid进程发送 第n个信号 kill -n -pid: 给pid进程组发送第n个信号 kill -n -1: 给除了init进程和本进程外其它所有进程发送第n个信号
int kill(int pid, int sig); 返回值: 成功 0 失败 -1 int pid: 0 同组进程; -1 除init外的所有进程 ; >0 进程号==pid int sig: 对应的信号 unsinged int alarm(unsinged int s); unsinged int s: 定时秒数 unsinged int: 失败 -1; 如果之前调用alarm函数,则返回上一个闹钟剩余时间
1.每个IPC对象有唯一的ID(操作对应IPC对象的凭证) 2.IPC对象创建后一直存在,直到被显示地删除(函数/命令) 3.每一个IPC对象有一个关联的key(多个进程找到同一个IPC对象,事先约定好) ipcs/ipcrm(查看操作指令) key == 0 表示私有 key: IPC_PRIVATE(0):表示私有 ftok():生产key值
key_t ftok(const char *path, int proj_id); 返回值: 成功 返回key 失败返回 EOF const char *path: 存在切可访问的文件路径 int proj_id: 用于生成key的数字,不能为0 且低八位有效
效率最高的进程间通信方式,进程可以直接读写内存,而不需要任何数据拷贝
共享内存在内核空间创建,只有被映射到用户空间才可以使用
当多个进程同时访问共享内存时,需要加入同步或者互斥机制配合使用 操作步骤: 1.创建/打开共享内存
int shmget(key_t key, int size, int shmflg); 返回值: 成功时返回共享内存ID, 失败返回EOF key_t key: 和共享内存关联的key, IPC_PRIVATE/ftok生成 int size: 共享内存的大小,以字节为单位 int shmflg: 共享内存标志位是否新建(IPC_CREAT|0666)及操作权限
2.映射到用户空间
void *shmat(int shmid, const void *shmaddr, int shmflg); 返回值: 成功 映射后的地址, 失败 返回(void *)-1 int shmid: 对应的共享内存ID const void *shmaddr: 要映射后的地址, NULL表示由系统自动映射 int shmflg: 0表示可读可写;SHM_RDONLY表示只读
3.读/写共享内存(通过指针访问/指针类型根据共享内存中存放的数据类型决定)
fgets() strcpy() ...
4.撤销共享内存映射
int shmdt(void *shmaddr); 返回值: 成功返回0, 失败返回EOF void *shmaddr: 共享内存映射的地址 注意: 一般不使用共享内存时应及时撤销映射,进程结束时自动撤销所有的共享 内存映射,若未取消映射,则无法删除对应的共享内存
5.删除共享内存(只是标记,直到所有相关进程退出时才删除)
int shmctl(int shmid, int cmd, struct shmid_ds *buf); 返回值:成功 0,失败 EOF int shmid: 要删除的共享内存ID int cmd: 要执行的操作 IPC_STAT IPC_SET IPC_RMID struct shmid_ds *buf: 存放共享内存的属性(删除时为NULL)
==注意==: 每块共享内存有大小限制: ipcs -l (cat /proc/sys/kernel/shmmax ) 多进程使用时,应由第一个进程创建,所有映射取消时才会真正的删除
1.使用最普遍 2.消息队列ID来唯一标识 3.是一个消息的列表,用户可以添加/读取消息 4.消息队列可以按照类型来发送/接收 使用步骤: 1.打开/创建消息队列 msgget
int masgget(key_t key, int msgflg); 返回值: 成功对应消息队列ID, 失败返回EOF key_t key: 关联的KEY int msgflg: 标志位 IPC_CREAT|0666
2.向消息队列发送消息 msgsnd
int msgsnd(int msgid, const void *msgp, size_t size, int msgflg); 返回值: 成功返回0, 失败返回 -1 int msgid: 对应消息队列ID const void *msgp: 要发送消息的缓冲区地址 size_t size: 指定本次发送消息的长度(正文长度) int msgflg: 标志位 0/IPC_NOWAIT (0阻塞 IPC_NOWAIT非阻塞(消息队列满时)) 注:
消息格式:
1.根据需求定义结构体类型 2.首成员类型必须为long,代表消息的类型 3.其它成员都属于正文 typedef struct{ long mtype; //类型,正整数 ... //成员 }MSG;
3.从消息队列接收消息 msgrcv
int msgrcv(int msgid, void *msgp, size_t size, long msgtype, int msgflg); 返回值: 成功返回消息的长度, 失败 -1 int msgid: 消息队列的id void *msgp: 接收的消息存放的缓冲区 size_t: 指定接收消息的长度(小于实际长度,剩余消息丢失;超过无影响) long msgtype: 指定接收消息的类型(0 按时间接收最早的消息; 负数按照优先级接收(几乎没见到)) int msgflg: 标志位 0/IPC_NOWAIT
4.控制消息队列 msgctl
int msgctl(int msgid, int cmd, struct msqid_ds *buf); 返回值: 成功0, 失败 -1 int msgid: 消息队列ID int cmd: 要执行的操作 IPC_STAT/IPC_SET/IPC_RMID struct msqid_ds *buf: 存放消息队列属性的地址