目录
一、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项目,发现自己线程中的信号通信还存在问题,还有待加强理解联系。今天学习了多进程的剩余通信方式:消息队列、共享内存、信号灯,其中使用共享内存通信时是异步的,要实现同步需要使用信号灯来实现。 必须深刻理解这三种通信的步骤。
加油!