下面是有关进程通信中 System V 代码的相关介绍,希望对你有所帮助!
目录
1. 消息队列 msg
示例代码
//发送端
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
struct message //带有标识的结构体
{
long mtype; //消息类型(固定)
char mtext[100]; //消息正文(可变)
};
int main()
{
// 以当前目录和序号1为系数产生一个对应的键值
// 创建(若存在则报错)key对应的MSG对象
int msgid;
msgid = msgget(ftok(".", 1), IPC_CREAT|0666);
struct message msg; //结构体全局变量
bzero(&msg, sizeof(msg)); //先清空发送的数据
msg.mtype = 1; //消息类型
fgets(msg.mtext, 100 ,stdin); //从键盘键入消息本体
msgsnd(msgid, &msg, strlen(msg.mtext) ,0); //发送消息
}
//接收端
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
struct message
{
long mtype;
char mtext[100];
};
int main()
{
// 以当前目录和序号1为系数产生一个对应的键值
// 创建(若存在则报错)key对应的MSG对象
int msgid;
msgid = msgget(ftok(".", 1), IPC_CREAT|0666);
struct message msgbuf;
bzero(&msgbuf, sizeof(msgbuf)); //先清空发送的数据
printf("wait...\n"); //等待接收提示
int msglong = msgrcv(msgid, &msgbuf, sizeof(msgbuf)-sizeof(long) ,1,0); //接收消息
if(msglong<0) //没有接收到
{
perror("msgrcv()");
}
else //接收到了
printf("%s\n", msgbuf.mtext); //打印文本信息
msgctl(msgid, IPC_RMID, NULL); //删除MSG对象,释放内存
return 0;
}
打开两个终端,编译后执行文件 ,可以发现发送端等待输入发送内容,接收端等待接收消息内容。
可以发现在发送端输入“111”后,接收端接收到“111”,只能执行一次就退出。
2. 共享内存 shm
示例代码
//发送端
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
// 以当前目录和序号1为系数产生一个对应的键值
// 创建(若存在则报错)key对应的SHM对象
char msg[100];
int shmid;
shmid = shmget(ftok(".", 1),1024, IPC_CREAT|0600);
if(shmid<0)
{
perror("failed");
exit(-1);
}
printf("shm id is : %d\n", shmid);
//映射
char * shmc = (char *)shmat(shmid, NULL, 0);
printf("shm映射 success\n");
//从键盘键入消息本体
fgets(msg, 99, stdin);
//memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1。
memcpy(shmc, msg, sizeof(msg));
//解除映射
shmdt(shmc);
printf("shm解除映射 success");
//删除SHM对象,释放内存
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
//接收端
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
// 以当前目录和序号1为系数产生一个对应的键值
// 创建(若存在则报错)key对应的SHM对象
int shmid;
shmid = shmget(ftok(".", 1),1024, IPC_CREAT|0600);
if(shmid<0)
{
perror("failed");
exit(-1);
}
printf("shm id is : %d\n", shmid);
//映射
char * shms = (char *)shmat(shmid, NULL, 0);
printf("shm映射 success\n");
while(strlen(shms)==0)
{
sleep(1);
printf("内容是:%s\n", shms);
}
//解除映射
shmdt(shms);
printf("shm解除映射 success");
//删除SHM对象,释放内存
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
从下方图片可看出
发送端第一行是打印的SHM对象ID,第二行是映射成功提示语,第三行是输入的内容“111”,第四行是解除映射成功提示语。
接收端第一行是打印的SHM对象ID,第二行是映射成功提示语,第三行往后等待接收输入的内容,接收到的内容是“111”。最后一行是解除映射成功提示语。
3. 信号量 sem
示例代码
//发送端
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
int main()
{
//1.获取共享内存key值
key_t key = ftok(".", 10);
//2.获取共享内存ID号
int shmid;
shmid = shmget(key,1024, IPC_CREAT|0600);
if(shmid<0)
{
perror("failed");
exit(-1);
}
printf("shm id is : %d\n", shmid);
//3.映射
char * shmc = (char *)shmat(shmid, NULL, 0);
//4.获取信号量key值
key_t key1 = ftok(".", 20);
//5.获取信号量ID
int semid;
semid = semget(key1, 2,IPC_CREAT|0666);
//6.初始化信号量的值
semctl(semid, 0, SETVAL, 1); //time
semctl(semid, 1, SETVAL, 0); //space
//time[0] : 1
struct sembuf semtime;
semtime.sem_num = 0; //time
semtime.sem_op = -1; //P操作
semtime.sem_flg = 0; //普通属性
//sapce[1] : 0
struct sembuf semspace;
semspace.sem_num = 1; //space
semspace.sem_op = 1; //V操作
semspace.sem_flg = 0; //普通属性
while(1)
{
semop(semid, &semtime, 1); //p操作 :-1后判断是否执行
scanf("%s", shmc);
semop(semid, &semspace, 1);
}
//解除映射
shmdt(shmc);
shmctl(shmid, IPC_RMID, NULL);
semctl(semid, 0, IPC_RMID);
return 0;
}
//接收端
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
int main()
{
//1.获取共享内存key值
key_t key = ftok(".", 10);
//2.获取共享内存ID号
int shmid;
shmid = shmget(key,1024, IPC_CREAT|0600);
if(shmid<0)
{
perror("failed");
exit(-1);
}
printf("shm id is : %d\n", shmid);
//3.映射
char * shmc = (char *)shmat(shmid, NULL, 0);
//4.获取信号量key值
key_t key1 = ftok(".", 20);
//5.获取信号量ID
int semid;
semid = semget(key1, 2,IPC_CREAT|0666);
//6.初始化信号量的值
semctl(semid, 0, SETVAL, 1); //time
semctl(semid, 1, SETVAL, 0); //space
struct sembuf semtime;
semtime.sem_num = 0; //time
semtime.sem_op = 1; //V操作
semtime.sem_flg = 0; //普通属性
struct sembuf semspace;
semspace.sem_num = 1; //space
semspace.sem_op = -1; //P操作
semspace.sem_flg = 0; //普通属性
while(1)
{
semop(semid, &semspace, 1);
printf("收到的数据是:%s\n", shmc);
sleep(2);
semop(semid, &semtime, 1);
}
return 0;
}
接收端和发送端都打印了SHM对象ID,等待发送端发送内容,接收端也在等待。
当发送端输入内容后,接收端接收到数据,并且可以持续发送接收。
上面是有关进程通信中 System V IPC 的相关介绍
如果喜欢请不吝给予三连支持!