一.消息队列
转载请附上:https://blog.csdn.net/qq_37978862/article/details/104575967
1.基本知识
存在于内核中
2.基本流程及函数
发送/接收:
(1) 申请key值
(2) 创建(打开)消息队列
(3) 发送消息(创建结构体)
typedef struct
{
long type;
char buf[128];
}msg_t;
(1)key_t key = ftok("/",5);
if( key<0 )
{
perror("ftok");
return -2;
}
(2)int msgid = msgget(key,IPC_CREAT|0777);
if( msgid<0 )
{
perror("msgget");
return -1;
}
(3)msg_t msg;
msgsnd(msgid,&msg,sizeof(msg),0);
//参数四:0 代表阻塞 IPC_NOWAIT 不阻塞
msgrcv(msgid,&msg,sizeof(msg),1,IPC_NOWAIT);
3.举例
#include<unistd.h>
#include<stdio.h>
#include<wait.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/ipc.h>
#include<sys/msg.h>
typedef struct
{
long type;
char buf[128];
}msg_t;
int main()
{
//创建key
key_t key = ftok("/etc",'t');
if(key<0)
{
perror("ftok");
return -1;
}
//创建消息队列描述符
int msgid = msgget(key,IPC_CREAT|0777);
if(msgid<0)
{
perror("msgget");
return -1;
}
//msgctl(msgid,IPC_RMID,NULL);
pid_t id = fork();
int x;
if( id>0 )
{
//接收消息
msg_t msg;
printf("rec:\n");
msgrcv(msgid,&msg,sizeof(msg)-sizeof(long),123,0);
printf("%s\n",msg.buf);
}
else if( id == 0)
{
//发送消息
sleep(1);
msg_t msg = {123,"5888"};
msgsnd(msgid,&msg,sizeof(msg)-sizeof(long),0);
wait(NULL);
printf("send complete!!!\n");
}
else
{
perror("fork");
return -1;
}
}
4.关于删除或查询的命令
命令行:
查询:ipcs -q
删除:ipcrm -q msgid
代码中:
msgctl(msgid,IPC_RMID,NULL);
二.共享内存
1.基本知识
a.存在内核区一块空间,进程可以将其映射到自己的私有地址空间
b.最为高效的进程间通信方式
2.步骤及具体函数
A.创建key ftok
B.创建 shmget
C.映射 shmat
D.解除映射 shmdt
key_t key = ftok("/",'a');
int shmid = shmget(key,1024,IPC_CREAT|0777);
//参数二:创建空间的大小
//参数三:权限
char *p = shmat(shmid,NULL,0);
//参数二:指定地址,系统自己创建
//参数三:0 可读写 , SHM_RDONLY只读
shmdt(p);
3.示例
#include<stdio.h>
#include<sys/types.h>
#include <sys/ipc.h>
#include<sys/shm.h>
#include<string.h>
int main()
{
//创建key
key_t key = ftok("/etc",'t');
if(key<0)
{
perror("ftok");
return -1;
}
//创建共享内存描述符
int shmid = shmget(key,1024,IPC_CREAT|0777);
if(shmid<0)
{
perror("msgget");
return -1;
}
pid_t id = fork();
if( id>0 )
{
//创建映射
char *p = shmat(shmid,NULL,0);
//参数三:可读写
strcpy(p,"hello world");
//解除映射
shmdt(p);
wait(NULL);
}
else if( id == 0)
{
//创建映射
char *p = shmat(shmid,NULL,SHM_RDONLY);
printf("%s\n",p);
shmdt(p);
}
else
{
perror("fork");
return -1;
}
}
4.删除及查询
命令行:
查询:ipcs -m
删除:ipcrm -m shmid