嵌入式学习Day30---Linux软件编程---进程间的通信
目录
一、Linux操作ipc对象(内存文件)的命令
1.1.查看命令
1.ipcs
2.ipcs -q(查看信息队列)
3.ipcs -m(查看共享内存)
4.ipcs -s(查看信号灯)
1.2.删除命令
1.ipcrm -q id
2.ipcrm -m id
3.ipcrm -s id
二、消息队列
2.1.实现步骤
1.创建key(ipc对象名称)值
2.创建消息队列
3.向消息队列中发送信息
4.从消息队列中取出信息
5.删除消息队列
三、共享内存
3.1.实现步骤
1.创建key值
2.创建共享内存
3.建立内存映射
4.取消内存映射
5.销毁共享内存
四、信号灯(与共享内存共用类似与线程中信号)
4.1.实现步骤
1.创建key
2.创建信号灯
3.设置信号灯
4.创建共享内存
5.建立内存映射
6.申请和释放信号灯
7.取消内存映射
8.销毁共享内存
9.删除信号灯
五、总结
一、Linux操作ipc对象(内存文件)的命令
1.1.查看命令
1.ipcs
2.ipcs -q(查看信息队列)
3.ipcs -m(查看共享内存)
4.ipcs -s(查看信号灯)
1.2.删除命令
前情提要(大写以key删除,小写以id删除),此处不做展示,还未创建新的。
1.ipcrm -q id
2.ipcrm -m id
3.ipcrm -s id
二、消息队列
2.1.实现步骤
1.创建key(ipc对象名称)值
函数接口:ftok
key_t ftok(const char *pathname, int proj_id);功能:创建一个IPC对象名称参数:pathname:文件的路径proj_id:项目ID(8bits)返回值:成功返回IPC对象名称失败返回-1
2.创建消息队列
函数接口:magget
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);功能:向消息队列中发送消息参数:msqid:消息队列的ID号msgp:发送消息的内容msgsz:发送消息的大小msgflg:消息属性 默认为0 返回值:成功返回0失败返回-1 struct msgbuf {long mtype; /* message type, must be > 0 */char mtext[1]; /* message data */};
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_STAT:获取消息队列的信息 返回值:成功返回0失败返回-1
三、共享内存
3.1.实现步骤
1.创建key值
函数接口:ftok
2.创建共享内存
函数接口:shmget
int shmget(key_t key, size_t size, int shmflg);功能:创建一个共享内存参数:key:IPC对象名称size:共享内存的大小shmflg:IPC_CREAT 创建 IPC_EXCL 如果存在就报错 返回值:成功返回共享内存ID号失败返回-1
3.建立内存映射
函数接口:shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);功能:将地址映射到共享内存中参数:shmid:共享内存ID号shmaddr:NULL: 让系统选择一个合适的地址映射到共享内存中shmflg:属性,默认为0 返回值:成功返回映射到共享空间的地址失败返回NULL
4.取消内存映射
函数接口:shmdt
int shmdt(const void *shmaddr);功能:解除映射空间参数:shmaddr:映射到共享内存中的地址返回值:成功返回0 失败返回-1
5.销毁共享内存
函数接口:shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);功能:向共享内存发送命令参数:shmid:共享内存ID号cmd:命令IPC_RMID 删除返回值:成功返回0 失败返回-1
四、信号灯(与共享内存共用类似与线程中信号)
4.1.实现步骤
1.创建key
函数接口:ftok
2.创建信号灯
函数接口:semget
int semget(key_t key, int nsems, int semflg); 功能:创建信号量数组 参数: key:IPC对象名称nsems:信号量个数semflg:信号量属性IPC_CREAT:创建一个信号量数组返回值: 成功返回0 失败返回-1
3.设置信号灯
函数接口:semctl
int semctl(int semid, int semnum, int cmd, ...);功能:向信号灯发送命令参数:IPC_RMID 删除信号灯SETVAL 设置第semnum-th信号量的值为arg.val 返回值:成功返回0 失败返回-1
4.创建共享内存
函数接口:shmget
5.建立内存映射
函数接口:shmat
6.申请和释放信号灯
函数接口:semop
int semop(int semid, struct sembuf *sops, size_t nsops);功能:对信号量完成申请和释放操作参数:semid:信号灯ID号sops:信号灯操作数组unsigned short sem_num; //操作信号量的下标short sem_op; //对信号量的操作 +1(释放信号量) -1(申请信号量)short sem_flg; //SEM_UNDO 操作结束后,信号量的值会恢复到原来的值nsops:数组元素个数 返回值:成功返回0 失败返回-1
7.取消内存映射
函数接口:shmdt
8.销毁共享内存
函数接口:shmctl
9.删除信号灯
函数接口:semctl
int semctl(int semid, int semnum, int cmd, ...);功能:向信号灯发送命令参数:IPC_RMID 删除信号灯SETVAL 设置第semnum-th信号量的值为arg.val 返回值:成功返回0 失败返回-1
注意:semctl功能很多,这里使用了他的设置和删除功能,其他两种里的也是 。
五、总结
2024年8月15日,学习的第30天,满满一个月啦!前几天再练手一个小项目mpalyer项目,发现自己线程中的信号通信还存在问题,还有待加强理解联系。今天学习了多进程的剩余通信方式:消息队列、共享内存、信号灯,其中使用共享内存通信时是异步的,要实现同步需要使用信号灯来实现。 必须深刻理解这三种通信的步骤。
加油!