ftok键值获取
#include <sys/types.h>
#include <sys/ipc.h>
/**
* [ftok 通过路径和id获取 System V IPC对象机制的唯一标识的键值key,使用于创建IPC对象(消息队列、共享内存、信号灯集)]
* @param pathname [表示路径(一般为工程的工作路径)]
* @param proj_id [id(一般位工程id)低8位]
* @return [成功返回获取的key值,失败返回-1且修改errno的值]
*/
key_t ftok(const char *pathname, int proj_id);
创建消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/**
* [msgget 获取消息队列的id]
* @param key [
* key标识消息的队列的键值
IPC_PRIVATE: 宏定义,其值位0,当key值使用该宏定义则每次都会创建一个新的消息队列。
当key为非IPC_PRIVATE,
如果该key值对应的消息队列已经存在,则获取之前创建好的消息队列的id号。
如果该key值对应的消息队列不存在,则在msgflg参数中使用IPC_CREAT宏定义创建消息队列,并返回消息的队列的id
* ]
* @param msgflg [
* msgflg表示获取到的消息队列的权限
设置消息队列的访问权限,也可设置消息的创建方式:
IPC_CREAT:创建消息队列;
IPC_CREAT | IPC_EXCL : 如果要创建的消息队列已经存在,则失败
* ]
* @return [成功返回消息队列的id号,失败返回-1且修改errno的值]
*/
int msgget(key_t key, int msgflg);
IPC对象机制shell命令
ipcs #查看所有IPC对象
ipcs -q #查看系统消息队列
ipcs -m #查看系统共享内存
ipcs -s #查看系统信号灯集
ipcrm #删除IPC对象
ipcrm -q 65538 #删除id=65538的消息队列
ipcrm -m 65538 #删除id=65538的共享内存
ipcrm -s 65538 #删除id=65538的信号灯集
消息队列的控制
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/**
* [msgctl 消息队列的控制]
* @param msqid [消息队列id]
* @param cmd [
* 消息的控制命令
* IPC_RMID:删除由msqid指示的消息队列,将它从系统中删除并破坏相关数据结构。
IPC_STAT:将msqid相关的数据结构中各个元素的当前值存入到由buf指向的结构中。
IPC_SET:将msqid相关的数据结构中的元素设置为由buf指向的结构中的对应值。
* ]
* @param buf [msqid_ds数据类型的地址,用来存放或更改消息队列的属性]
* @return [成功返回 0 失败返回-1]
*/
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
发送
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/**
* [msgsnd 向消息队列中添加消息]
* @param msqid [消息队列的id号]
* @param msgp [
* 所有添加到消息队列中的消息的地址:
struct msgbuf {
long mtype; / message type, must be > 0 /
char mtext[1]; / message data:此处的大小供参考,需要根据需求定义 /
};
* ]
* @param msgsz [消息队列消息正文空间的大小]
* @param msgflg [
* 表示添加消息的方式
0:阻塞方式发送,msgsnd调用阻塞直到条件满足为止。
IPC_NOWAIT: 非阻塞方式发送,若消息没有立即发送则调用该函数的进程会立即返回
* ]
* @return [成功返回0,失败返回-1且修改errno的值]
*/
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
实例
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data:此处的大小供参考,需要根据需求定义 */
};
int main()
{
key_t key;
int msgid;
int ret;
struct msgbuf mymsgbuf;
/* 获取IPC对象的键 */
key = ftok(".", 'm');
if (key == -1) {
perror("ftok");
return -1;
}
/* 创建消息队列 */
msgid = msgget(key, IPC_CREAT | 0777);
if (msgid == -1) {
perror("msgget");
return -1;
}
while(1) {
/* 设置消息的类型 */
printf("input msg type: ");
scanf("%ld", &(mymsgbuf.mtype));
getchar();
/* 设置消息的正文 */
printf("input msg text: ");
fgets(mymsgbuf.mtext, sizeof(mymsgbuf.mtext), stdin);
/* 发送消息 */
ret = msgsnd(msgid, (const void *)&mymsgbuf, sizeof(mymsgbuf.mtext), 0);
if (ret == -1) {
perror("msgsnd");
return -1;
}
}
/* 删除消息队列 */
ret = msgctl(msgid, IPC_RMID, NULL);
if (ret == -1) {
perror("msgctl->IPC_RMID");
return -1;
}
system("ipcs -q");
}
接收
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/**
* [msgrcv 接收消息]
* @param msqid [消息队列的id号]
* @param msgp [存放消息结构体的地址]
* @param msgsz [消息正文空间的大小]
* @param msgtyp [
* 表示接收消息的类型
* = 0 此时从消息队列中的第一条消息开始依次接收
> 0 按照类型msgtyp接收,如果在msgflg中使用了宏定义MSG_EXCEPT,则接收不等于msgtyp的消息。
< 0 读取类型为小于等于-msgtyp的消息
* ]
* @param msgflg [
* 读取消息的方式
* 0:msgrcv调用阻塞直到接收消息成功为止。
MSG_NOERROR:若返回的消息字节数比nbytes字节数多,则消息就会截短到nbytes字节,且不通知消息发送进程。
IPC_NOWAIT:调用进程会立即返回。若没有收到消息则立即返回-1。返回值:成功返回读取消息的长度,失败返回-1
* ]
* @return [成功返回消息正文字节数,失败返回-1.]
*/
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
实例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data:此处的大小供参考,需要根据需求定义 */
};
int main()
{
key_t key;
int msgid;
int ret;
struct msgbuf mymsgbuf;
/* 获取IPC对象的键 */
key = ftok(".", 'm');
if (key == -1) {
perror("ftok");
return -1;
}
/* 创建消息队列 */
msgid = msgget(key, IPC_CREAT | 0777);
if (msgid == -1) {
perror("msgget");
return -1;
}
while(1) {
/* 接收消息 */
ret = msgrcv(msgid, (void *)&mymsgbuf, sizeof(mymsgbuf.mtext), -3, 0);
if (ret == -1) {
perror("msgsnd");
return -1;
}
printf("%ld:%s\n", mymsgbuf.mtype, mymsgbuf.mtext);
sleep(1);
}
/* 删除消息队列 */
ret = msgctl(msgid, IPC_RMID, NULL);
if (ret == -1) {
perror("msgctl->IPC_RMID");
return -1;
}
system("ipcs -q");
}
网友评论