ipcs
;单独查看消息队列
:ipcs -q
;单独查看共享内存段
:ipcs -m
;单独查看信号量数组
:ipcs -s
;单独删除消息队列
:ipcrm -q msqid
;单独删除共享内存段
:ipcrm -m shmid
;单独删除信号量数组
:ipcrm -s semid
; #include
#include
key_t ftok(const char *pathname, int proj_id);
/*
参数:
pathname: 路径和文件名(必须是一个已存在的)
proj_id: 填充的是任意一个字符
返回值:
成功 键值
失败 -1 重置错误码
*/
#include
#include
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
key_t key = ftok("/home/linux/work/MSG", 0x1234);
if(-1 == key)
{
perror("ftok error");
exit(1);
}
printf("key = %x\n",key);
struct stat lk;
stat("/home/linux/work/MSG",&lk);
printf("proj_id=%x,dev = %lx,inode=%lx\n",0x1234,lk.st_dev,lk.st_ino);
return 0;
}
key = 34011052
proj_id=1234,dev = 801,inode=2a1052
总结:键值key = proj_id(低8位)+dev(低8位)+inode(低16位)
;
消息队列:
1、基于内核实现,必须在内核
空间创建消息队列
;
2、消息队列中的消息
由类型
和正文
组成;
3、消息队列的默认大小为16KB
;
运行过程:
1、进程1将消息写入
到消息队列,进程2根据消息的类型
从消息队列中取得对应的消息
;
2、进程1向消息队列中发送
消息,可以采用阻塞或者非阻塞
的方式;
3、进程2从消息队列中收取
消息,也可以采用阻塞或者非阻塞
的方式;
常用的接口函数:
msgget函数:
功能:创建或者获取一个消息队列;
#include
#include
#include
int msgget(key_t key, int msgflg);
/*
参数:
key: 键值
key 通过ftok获取的
IPC_PRIVATE 表示只有亲缘进程间能只用
msgflg:消息队列的标志位
IPC_CREAT|0666 或者 IPC_CREAT|IPC_EXCL|0666
返回值:
成功 消息队列的id
失败 -1 重置错误码
*/
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
/*
参数:
msqid:消息队列的id
msgp: 要写入的数据的首地址
msgsz:消息正文的大小
msgflg:标志位 0 阻塞发送 IPC_NOWAIT 非阻塞发送
返回值:
成功 0
失败 -1 重置错误码
*/
struct msgbuf {
long mtype; /* 消息的类型 必须大于 0 */
char mtext[1]; /* 消息正文 可以自定义 */
};
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
/*
参数:
msqid:消息队列的id
msgp: 用来保存接收的数据的缓冲区的首地址
msgsz:消息正文的大小
msgtyp:要接受的消息的类型
0 :接收消息队列中第一条消息
>0 : 接收指定类型的第一条消息
<0 :一般不使用,
表示接收消息队列中第一条类型最小的小于msgtyp的绝对值的消息
3-2-5-500-200-8
读取时,类型传 -200
读取的顺序 2-3-5
msgflg:标志位 0 阻塞接收 IPC_NOWAIT 非阻塞接收
返回值:
成功 实际读到的正文的字节数
失败 -1 重置错误码
*/
struct msgbuf {
long mtype; /* 消息的类型 必须大于 0 */
char mtext[1]; /* 消息正文 可以自定义 */
};
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
/*
参数:
msqid:消息队列id
cmd:指令
IPC_STAT:获取消息队列的属性
IPC_SET:设置消息队列的属性
IPC_RMID:立即删除消息队列
只有消息队列的创建者和所有者以及root用户可以删除消息队列
msgctl函数的第三个参数被忽略
buff:
返回值:
成功 0
失败 -1 重置错误码
*/
#include
#include
#include
#include
#include
#include
#include
//不关注类型
typedef struct msg
{
long mtype; //消息的类型 必须大于 0
char buf[256]; //消息正文 可以自定义
}msg_t;
int main(int argc, char const *argv[])
{
//获取IPC通信的键值
key_t key = ftok("/home/linux/work/MSG", 'k');
if(-1 == key)
{
perror("ftok error");
}
//创建一个消息队列
int msqid = msgget(key, IPC_CREAT|0666);
if(-1 == msqid)
{
perror("msgget error");
}
printf("msqid = %d\n", msqid);
msg_t msg = {.mtype = 100};
while(1)
{
fgets(msg.buf,sizeof(msg.buf),stdin);
msg.buf[strlen(msg.buf)-1] = '\0';
if(!strncmp(msg.buf,"quit",4))
{
break;
}
//向消息队列中写入一条消息
msgsnd(msqid,&msg,sizeof(msg)-sizeof(msg.mtype),0);
}
//删除消息队列
if(-1 == msgctl(msqid,IPC_RMID,NULL))
{
perror("msgctl error");
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
//不关注类型
typedef struct msg
{
long mtype; //消息的类型 必须大于 0
char buf[256]; //消息正文 可以自定义
}msg_t;
int main(int argc, char const *argv[])
{
//获取IPC通信的键值
key_t key = ftok("/home/linux/work/MSG", 'k');
if(-1 == key)
{
perror("ftok error");
}
//创建一个消息队列
int msqid = msgget(key, IPC_CREAT|0666);
if(-1 == msqid)
{
perror("msgget error");
}
printf("msqid = %d\n", msqid);
msg_t msg;
int type = 0;
while(1)
{
//忽略类型,每次都输入0
scanf("%d",&type);
msgrcv(msqid, &msg,sizeof(msg)-sizeof(msg.mtype), type, 0);
printf("%ld:[%s]\n",msg.mtype,msg.buf);
}
//删除消息队列
if(-1 == msgctl(msqid,IPC_RMID,NULL))
{
perror("msgctl error");
}
return 0;
}
linux@ubuntu:~/work/MSG$ gcc w1.c -o w1
linux@ubuntu:~/work/MSG$ ./w1
msqid = 5
hello
china
hi
linux@ubuntu:~/work/MSG$ gcc r1.c -o r1
linux@ubuntu:~/work/MSG$ ./r1
msqid = 5
0
100:[hello]
0
100:[china]
0
100:[hi]
//关注类型
#include
#include
#include
#include
#include
#include
#include
//消息结构体
typedef struct MSG
{
long mtype;
int id;
char name[32];
int score;
}msg_t;
int main(int argc, char const *argv[])
{
//获取IPC通信的键值
key_t key = ftok("/home/linux/work/MSG", 'k');
if(-1 == key)
{
perror("ftok error");
}
//创建一个消息队列
int msqid = msgget(key, IPC_CREAT|0666);
if(-1 == msqid)
{
perror("msgget error");
}
printf("msqid = %d\n", msqid);
//发送消息
msg_t msg1 = {
.mtype = 120,
.id = 1001,
.name = "lk",
.score = 99,
};
msgsnd(msqid, &msg1, sizeof(msg1) - sizeof(long), 0);
msg_t msg2 = {
.mtype = 110,
.id = 1002,
.name = "smd",
.score = 98,
};
msgsnd(msqid, &msg2, sizeof(msg2) - sizeof(long), 0);
msg_t msg3 = {
.mtype = 130,
.id = 1003,
.name = "wjy",
.score = 94,
};
msgsnd(msqid, &msg3, sizeof(msg3) - sizeof(long), 0);
msg_t msg4 = {
.mtype = 111,
.id = 1004,
.name = "syj",
.score = 94,
};
msgsnd(msqid, &msg4, sizeof(msg4) - sizeof(long), 0);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
//消息结构体
typedef struct MSG
{
long mtype;
int id;
char name[32];
int score;
}msg_t;
int main(int argc, char const *argv[])
{
//获取IPC通信的键值
key_t key = ftok("/home/linux/work/MSG", 'k');
if(-1 == key)
{
perror("ftok error");
}
//创建一个消息队列
int msqid = msgget(key, IPC_CREAT|0666);
if(-1 == msqid)
{
perror("msgget error");
}
printf("msqid = %d\n", msqid);
msg_t msg;
long type;
while(1)
{
memset(&msg, 0, sizeof(msg_t));
printf("请输入要接收消息的类型\n");
scanf("%ld", &type);
msgrcv(msqid, &msg, sizeof(msg) - sizeof(long), type, 0);
printf("[%ld][%d][%s][%d]\n",msg.mtype, msg.id, msg.name, msg.score);
}
//删除消息队列
if(-1 == msgctl(msqid, IPC_RMID,NULL))
{
perror("msgctl error");
}
return 0;
}
linux@ubuntu:~/work/MSG$ gcc w2.c -o w2
linux@ubuntu:~/work/MSG$ ./w2
msqid = 7
linux@ubuntu:~/work/MSG$ gcc r2.c -o r2
linux@ubuntu:~/work/MSG$ ./r2
msqid = 7
请输入要接收消息的类型
120
[120][1001][lk][99]
请输入要接收消息的类型
111
[111][1004][syj][94]
请输入要接收消息的类型
130
[130][1003][wjy][94]
请输入要接收消息的类型
110
[110][1002][smd][98]