向消息队列中写入数据
#include
//定义一个发送消息的结构体类型
struct msgbuf
{
long mtype; //消息类型
char mtext[1024]; //消息正文大小
};
//宏定义消息正文的大小
#define SIZE (sizeof(struct msgbuf)-sizeof(long))
int main(int argc, const char *argv[])
{
//1、创建key值
key_t key = ftok("/", 'k');
if(key == -1)
{
perror("key create error");
return -1;
}
//此时key已经创建出来
printf("key = %#x\n", key);
//2、创建消息队列
int msgid = msgget(key, IPC_CREAT|0664);
if(msgid == -1)
{
perror("msgget error");
return -1;
}
printf("msgid = %d\n", msgid); //输出消息队列id号
//3、向消息队列中存放数据
//定义一个消息类型的变量
struct msgbuf buf;
while(1)
{
//输入消息内容
printf("请输入您要发送的类型:");
scanf("%ld", &buf.mtype);
printf("请输入消息内容:");
scanf("%s", buf.mtext);
//将消息放入消息队列中
msgsnd(msgid, &buf, SIZE, 0);
//判断退出条件
if(strcmp(buf.mtext, "quit") == 0)
{
break;
}
}
//4、删除消息队列
if(msgctl(msgid, IPC_RMID, NULL) == -1)
{
perror("msgctl error");
return -1;
}
return 0;
}
2> 从消息队列中读取数据
#include
//定义一个发送消息的结构体类型
struct msgbuf
{
long mtype; //消息类型
char mtext[1024]; //消息正文大小
};
//宏定义消息正文的大小
#define SIZE (sizeof(struct msgbuf)-sizeof(long))
int main(int argc, const char *argv[])
{
//1、创建key值
key_t key = ftok("/", 'k');
if(key == -1)
{
perror("key create error");
return -1;
}
//此时key已经创建出来
printf("key = %#x\n", key);
//2、创建消息队列
int msgid = msgget(key, IPC_CREAT|0664);
if(msgid == -1)
{
perror("msgget error");
return -1;
}
printf("msgid = %d\n", msgid); //输出消息队列id号
//3、从消息队列中读取数据
//定义一个消息类型的变量
struct msgbuf buf;
while(1)
{
//将消息从消息队列中读取出来
msgrcv(msgid, &buf, SIZE, 0, 0);
//参数1:消息队列id
//参数2:容器起始地址
//参数3:消息正文大小
//参数4:要读取的消息类型
//参数5:是否阻塞
//将读取的消息打印出来
printf("收到消息:%s\n", buf.mtext);
//判断退出条件
if(strcmp(buf.mtext, "quit") == 0)
{
break;
}
}
//4、删除消息队列
return 0;
}
1> 发送端
#include
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
//1、创建一个key值
key_t key = ftok("/", 't');
if(key == -1)
{
perror("ftok error");
return -1;
}
printf("key = %#x\n", key);
//2、通过key值创建共享内存段
int shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664);
if(shmid == -1)
{
perror("shmget error");
return -1;
}
printf("shmid = %d\n", shmid);
//3、将共享内存段映射到用户空间
char *addr = (char *)shmat(shmid, NULL, 0);
//参数1:共享内存的id
//参数2:让系统自动选择分配的页地址
//参数3:0表示对共享内存有读写权限
if(addr == (void*)-1 )
{
perror("shmat error");
return -1;
}
printf("addr = %p\n", addr); //输出映射的虚拟地址
//4、使用共享内存段
//char buf[128] = "";
while(1)
{
printf("请输入>>>>");
fgets(addr, PAGE_SIZE, stdin); //向共享内存中输入数据
addr[strlen(addr)-1] = 0; //将'\n'换成'\0'
//判断退出条件
if(strcmp(addr, "quit") == 0)
{
break;
}
}
//5、取消映射
//取消addr对共享内存的映射关系
if(shmdt(addr) == -1)
{
perror("shmdt error");
return -1;
}
//6、删除共享内存
return 0;
}
2> 接受端
#include
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
//1、创建一个key值
key_t key = ftok("/", 't');
if(key == -1)
{
perror("ftok error");
return -1;
}
printf("key = %#x\n", key);
//2、通过key值创建共享内存段
int shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664);
if(shmid == -1)
{
perror("shmget error");
return -1;
}
printf("shmid = %d\n", shmid);
//3、将共享内存段映射到用户空间
char *addr = (char *)shmat(shmid, NULL, 0);
//参数1:共享内存的id
//参数2:让系统自动选择分配的页地址
//参数3:0表示对共享内存有读写权限
if(addr == (void*)-1 )
{
perror("shmat error");
return -1;
}
printf("addr = %p\n", addr); //输出映射的虚拟地址
//4、使用共享内存段
//char buf[128] = "";
while(1)
{
//读取共享内存中的数据
printf("共享内存中的数据为: %s\n", addr);
//判断退出条件
if(strcmp(addr, "quit") == 0)
{
break;
}
}
//5、取消映射
if(shmdt(addr) == -1)
{
perror("shmdt error");
return -1;
}
//6、删除共享内存
if(shmctl(shmid, IPC_RMID, NULL) == -1)
{
perror("shmctl error");
return -1;
}
return 0;
}
信号灯集的使用
1> shmsnd.c
#include
#include"sem.h" //信号灯集操作的头文件
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
//11、创建一个信号灯集
int semid = create_sem(2); //创建一个信号灯集包含两个灯,并初始化
if(semid == -1)
{
perror("create_sem error");
return -1;
}
//1、创建一个key值
key_t key = ftok("/", 't');
if(key == -1)
{
perror("ftok error");
return -1;
}
printf("key = %#x\n", key);
//2、通过key值创建共享内存段
int shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664);
if(shmid == -1)
{
perror("shmget error");
return -1;
}
printf("shmid = %d\n", shmid);
//3、将共享内存段映射到用户空间
char *addr = (char *)shmat(shmid, NULL, 0);
//参数1:共享内存的id
//参数2:让系统自动选择分配的页地址
//参数3:0表示对共享内存有读写权限
if(addr == (void*)-1 )
{
perror("shmat error");
return -1;
}
printf("addr = %p\n", addr); //输出映射的虚拟地址
//4、使用共享内存段
//char buf[128] = "";
while(1)
{
//22、P操作
P(semid, 1); //等待1号灯的资源
printf("请输入>>>>");
fgets(addr, PAGE_SIZE, stdin); //向共享内存中输入数据
addr[strlen(addr)-1] = 0; //将'\n'换成'\0'
//33、V操作
V(semid, 0); //释放0号灯的资源
//判断退出条件
if(strcmp(addr, "quit") == 0)
{
break;
}
}
//5、取消映射
//取消addr对共享内存的映射关系
if(shmdt(addr) == -1)
{
perror("shmdt error");
return -1;
}
//6、删除共享内存
return 0;
}
2> shmrcv.c
#include
#include"sem.h" //信号灯集的头文件
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
//11、打开一个信号灯集
int semid = create_sem(2);
if(semid == -1)
{
perror("create_sem error");
return -1;
}
//1、创建一个key值
key_t key = ftok("/", 't');
if(key == -1)
{
perror("ftok error");
return -1;
}
printf("key = %#x\n", key);
//2、通过key值创建共享内存段
int shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664);
if(shmid == -1)
{
perror("shmget error");
return -1;
}
printf("shmid = %d\n", shmid);
//3、将共享内存段映射到用户空间
char *addr = (char *)shmat(shmid, NULL, 0);
//参数1:共享内存的id
//参数2:让系统自动选择分配的页地址
//参数3:0表示对共享内存有读写权限
if(addr == (void*)-1 )
{
perror("shmat error");
return -1;
}
printf("addr = %p\n", addr); //输出映射的虚拟地址
//4、使用共享内存段
//char buf[128] = "";
while(1)
{
//22、P操作
P(semid, 0); //申请0号灯的资源
//读取共享内存中的数据
printf("共享内存中的数据为: %s\n", addr);
//33、V操作
V(semid, 1); //释放1号灯的资源
//判断退出条件
if(strcmp(addr, "quit") == 0)
{
break;
}
}
//5、取消映射
if(shmdt(addr) == -1)
{
perror("shmdt error");
return -1;
}
//6、删除共享内存
if(shmctl(shmid, IPC_RMID, NULL) == -1)
{
perror("shmctl error");
return -1;
}
//44、删除信号灯集
del_sem(semid);
return 0;
}