System V IPC
特点:
与管道有所不同,它完全使用了不同的实现机制,与文件没任何的关系,也就是说内核不再以文件的形式来管理System V IPC
System V IPC不再以文件的形式存在,因此没有文件描述符这个东西,但是它有类似的“标识符”
任何进程之间通信时,都可以使用System V IPC来通信
POSIX也可以支持消息队列、共享内存、信号量能在unix下运行
消息队列的本质就是由内核创建的用于存放消息的链表,由于是存放消息的,所以我们就把这个链表称为消息队列。
int msgget(key_t key, int msgflg);
#include
#include
#include
#include
#include
#include
#define MSGNAME "./msg_file"
int main(int argc, char const *argv[])
{
key_t key;
int msgid;
key = ftok(MSGNAME, 'k');
msgid = msgget(key, IPC_CREAT | 0655);
if (msgid < 0)
{
perror("msgid error!");
exit(1);
}
printf("msgid = %d\n",msgid);
return 0;
}
进程结束时,system v ipc不会自动删除,进程结束后,使用ipcs依然能够查看到
#include
#include
#include
#include
#include
#include
#define MSGNAME "./msg_file"
int main(int argc, char const *argv[])
{
key_t key;
int msgid;
key = ftok(MSGNAME, 'k');
msgid = msgget(key, IPC_CREAT | 0655);
if (msgid < 0)
{
perror("msgid error!");
exit(1);
}
printf("key = %x\n", key);
printf("msgid = %d\n", msgid);
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
int msgsnd(int msqid,const void *msgp, size_t msgsz,int msgflg);
ssize_ t msgrcv(int msqid, void *msgp, size_ t msgsz, long msgtyp, int msgflg);
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MSGNAME "./msg_file"
int msgid;
struct msgbuf
{
long mtype;
char mtext[1024];
};
void my_exit(int msg)
{
msgctl(msgid,IPC_RMID,NULL);
}
int main(int argc, char const *argv[])
{
key_t key;
pid_t pid;
signal(SIGINT, my_exit);
key = ftok(MSGNAME, 'k');
msgid = msgget(key, IPC_CREAT | 0655);
if (msgid < 0)
{
perror("msgid error!");
exit(1);
}
printf("key = %x\n", key);
printf("msgid = %d\n", msgid);
pid = fork();
if (pid < 0)
{
perror("fork perror!\n");
exit(1);
}
if (pid == 0)
{
long mtype;
char buffer[1024];
struct msgbuf pmsgbuf;
while (1)
{
memset(buffer, 0, sizeof(buffer));
memset(&pmsgbuf, 0, sizeof(struct msgbuf));
printf("Please input send msg:\n");
scanf("%s", buffer);
strcpy(pmsgbuf.mtext, buffer);
printf("Please input send msg id:\n");
scanf("%ld", &mtype);
pmsgbuf.mtype = mtype;
if(msgsnd(msgid,(void *)&pmsgbuf,sizeof(pmsgbuf),IPC_NOWAIT) < 0)
{
perror("msg snd error!");
exit(1);
}
}
}
else if(pid > 0)
{
size_t size;
long mtype;
char buffer[1024];
struct msgbuf pmsgbuf;
while (1)
{
memset(buffer, 0, sizeof(buffer));
memset(&pmsgbuf, 0, sizeof(struct msgbuf));
size = msgrcv(msgid, &pmsgbuf,sizeof(pmsgbuf),3,0);
if (size < 0)
{
perror("msg rcv error!");
exit(1);
}
printf("recv data:%s\n", pmsgbuf.mtext);
sleep(1);
}
}
return 0;
}
多个进程是如何共享到同一个消息队列?
消息队列的特点
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MSGNAME "./msg_file"
struct msgbuf
{
long mtype;
char mtext[1024];
};
int main(int argc, char const *argv[])
{
key_t key;
key = ftok(MSGNAME, 'k');
int msgid = msgget(key, IPC_CREAT | 0777);
if (msgid < 0)
{
perror("msgid error!");
exit(1);
}
printf("key = %x\n", key);
printf("msgid = %d\n", msgid);
size_t size;
long mtype;
char buffer[1024];
struct msgbuf pmsgbuf;
while (1)
{
memset(buffer, 0, sizeof(buffer));
memset(&pmsgbuf, 0, sizeof(struct msgbuf));
size = msgrcv(msgid, &pmsgbuf,sizeof(pmsgbuf),3,0);
if (size < 0)
{
perror("msg rcv error!");
exit(1);
}
printf("recv data:%s\n", pmsgbuf.mtext);
sleep(1);
}
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MSGNAME "./msg_file"
struct msgbuf
{
long mtype;
char mtext[1024];
};
int main(int argc, char const *argv[])
{
key_t key;
key = ftok(MSGNAME, 'k');
int msgid = msgget(key, 0777 | IPC_CREAT);
if (msgid < 0)
{
perror("msgid error!");
exit(1);
}
printf("key = %x\n", key);
printf("msgid = %d\n", msgid);
size_t size;
long mtype;
char buffer[1024];
struct msgbuf pmsgbuf;
while (1)
{
memset(buffer, 0, sizeof(buffer));
memset(&pmsgbuf, 0, sizeof(struct msgbuf));
printf("Please input send msg:\n");
scanf("%s", buffer);
strcpy(pmsgbuf.mtext, buffer);
printf("Please input send msg id:\n");
scanf("%ld", &mtype);
pmsgbuf.mtype = mtype;
if(msgsnd(msgid,(void *)&pmsgbuf,sizeof(pmsgbuf),IPC_NOWAIT) < 0)
{
perror("msg snd error!");
exit(1);
}
}
}