作业内容
- 要求AB进程通过消息队列做通信
1)A进程发送一句话,B进程接收打印
2)然后B进程发送给A进程一句话,A进程接收打印
3)重复1,2步骤,直到A进程或者B进程收到quit,退出AB进程;
4)AB进程能够随时收发数据 - A进程写入一个整型,在该整型后,写入一个字符串
B进程将共享内存中的整型以及字符串读取出来;
1. AB进程通过消息队列进行通信
进程A代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
typedef void (*sighandler_t)(int);
void handler(int sig)
{
wait(NULL);
exit(0);
}
struct msgbuf
{
long mtype;
char mtext[128];
};
int main(int argc, const char *argv[])
{
key_t key = ftok("./",1);
if(key < 0)
{
perror("ftok");
return -1;
}
int msqid = msgget(key,IPC_CREAT|0664);
if(msqid < 0)
{
perror("msgget");
return -1;
}
pid_t pid = fork();
if(pid > 0)
{
struct msgbuf ra;
while(1)
{
sighandler_t s = signal(SIGCHLD,handler);
if(SIG_ERR == s)
{
perror("signal");
return -1;
}
if(msgrcv(msqid,&ra,sizeof(ra.mtext),2,0) < 0)
{
if(errno != 4)
{
perror("msgrcv");
return -1;
}
}
if(strcasecmp(ra.mtext,"quit") == 0)
{
printf("对方已退出\n");
kill(pid,SIGKILL);
wait(NULL);
exit(0);
}
printf("A接收到B的消息:%s\n",ra.mtext);
printf("A:请输入消息内容:\n");
}
}
else if(0 == pid)
{
struct msgbuf wa;
wa.mtype = 1;
while(1)
{
printf("A:请输入消息内容:\n");
fgets(wa.mtext,sizeof(wa.mtext),stdin);
wa.mtext[strlen(wa.mtext)-1] = 0;
msgsnd(msqid,&wa,sizeof(wa.mtext),0);
if(strcasecmp(wa.mtext,"quit") == 0)
{
printf("退出成功\n");
exit(0);
}
}
}
else
{
perror("fork");
return -1;
}
return 0;
}
进程B代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
typedef void (*sighandler_t)(int);
void handler(int sig)
{
wait(NULL);
exit(0);
}
struct msgbuf
{
long mtype;
char mtext[128];
};
int main(int argc, const char *argv[])
{
key_t key = ftok("./",1);
if(key < 0)
{
perror("ftok");
return -1;
}
int msqid = msgget(key,IPC_CREAT|0664);
if(msqid < 0)
{
perror("msgget");
return -1;
}
pid_t pid = fork();
if(pid > 0)
{
struct msgbuf rb;
while(1)
{
sighandler_t s = signal(SIGCHLD,handler);
if(SIG_ERR == s)
{
perror("signal");
return -1;
}
if(msgrcv(msqid,&rb,sizeof(rb.mtext),1,0) < 0)
{
if(errno != 4)
{
perror("msgrcv");
return -1;
}
}
if(strcasecmp(rb.mtext,"quit") == 0)
{
printf("对方已退出\n");
kill(pid,SIGKILL);
wait(NULL);
exit(0);
}
printf("B接收到A的消息:%s\n",rb.mtext);
printf("B:请输入消息内容:\n");
}
}
else if(0 == pid)
{
struct msgbuf wb;
wb.mtype = 2;
while(1)
{
printf("B:请输入消息内容:\n");
fgets(wb.mtext,sizeof(wb.mtext),stdin);
wb.mtext[strlen(wb.mtext)-1] = 0;
msgsnd(msqid,&wb,sizeof(wb.mtext),0);
if(strcasecmp(wb.mtext,"quit") == 0)
{
printf("退出成功\n");
exit(0);
}
}
}
else
{
perror("fork");
return -1;
}
return 0;
}
测试结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/9d555b505f8d4b6a9a49c702179155c2.png#pic_center)
2. AB进程通过共享内存进行通信
进程A代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, const char *argv[])
{
key_t key = ftok("./",3);
if(key == -1)
{
perror("ftok");
return -1;
}
int shmid = shmget(key,128,IPC_CREAT|0664);
if(shmid < 0)
{
perror("shmget");
return -1;
}
void* shmaddr = shmat(shmid,NULL,0);
int* pa1 = (int*)shmaddr;
printf("请输入一个整型数:\n");
scanf("%d",pa1);
getchar();
char* pa2 = (char*)(pa1+1);
printf("请输入一个字符串:\n");
fgets(pa2,128,stdin);
return 0;
}
进程B代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, const char *argv[])
{
key_t key = ftok("./",3);
if(key == -1)
{
perror("ftok");
return -1;
}
int shmid = shmget(key,128,IPC_CREAT|0664);
if(shmid < 0)
{
perror("shmget");
return -1;
}
void* shmaddr = shmat(shmid,NULL,SHM_RDONLY);
int* pb1 = (int*)shmaddr;
char* pb2 = (char*)(pb1+1);
printf("整型:%d\n",*pb1);
printf("字符串:%s",pb2);
return 0;
}
测试结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/19087c3ad85d4d808142a81aa576ec9e.png#pic_center)