作业一:使用消息队列实现AB进程对话
① 打开两个终端,要求实现AB进程对话
- A进程先发送一句话给B进程,B进程接收后打印
- B进程再回复一句话给A进程,A进程接收后打印
- 重复1.2步骤,当收到quit后,要结束AB进程
② 实现随时收发:用多进程 多线程。
1)A终端
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
/***************************A终端***************************/
struct msgbuf
{
long mtype; //消息类型,必须大于0
char mtext[128]; //消息内容
};
int main(int argc, const char *argv[])
{
//创建key值
key_t key = ftok("/home/ubuntu",1);
if(key < 0)
{
perror("mkfifo");
return -1;
}
//创建消息队列
int msqid = msgget(key, IPC_CREAT|0664) ;
if(msqid< 0)
{
perror("mkfifo");
return -1;
}
struct msgbuf Abuf;
ssize_t res=0;
//创建子进程
pid_t cpid=fork();
if(cpid > 0) //父进程(发送),A终端发送消息,B终端接收消息
{
while(1)
{
Abuf.mtype=1;
scanf("%s",Abuf.mtext);
if(msgsnd(msqid, &Abuf,sizeof(Abuf.mtype),0) < 0)
{
perror("msgsnd");
return -1;
}
if(strcmp(Abuf.mtext,"quit")==0)
break;
}
}
else if(0 == cpid) //子进程(接收),B终端发送消息,A终端接收
{
while(1)
{
msgrcv(msqid,&Abuf,sizeof(Abuf.mtext),2,0);
if(res < 0)
{
perror("msgrcv");
return -1;
}
if(strcmp(Abuf.mtext,"quit")==0)
break;
printf("%s\n",Abuf.mtext);
}
kill(getppid(),2);
}
else
{
perror("fork");
return -1;
}
return 0;
}
2)B终端
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
/***************************B终端***************************/
struct msgbuf
{
long mtype; //消息类型,必须大于0
char mtext[128]; //消息内容
};
int main(int argc, const char *argv[])
{
//创建key值
key_t key = ftok("/home/ubuntu",1);
if(key < 0)
{
perror("mkfifo");
return -1;
}
//printf("key = %#x\n",key);
//创建消息队列
int msqid = msgget(key, IPC_CREAT|0664) ;
if(msqid< 0)
{
perror("mkfifo");
return -1;
}
struct msgbuf Bbuf;
ssize_t res=0;
pid_t cpid=fork();
if(cpid > 0) //父进程(接收),A终端发送消息,B终端接收消息
{
while(1)
{
Bbuf.mtype=2;
scanf("%s",Bbuf.mtext);
if(msgsnd(msqid, &Bbuf,sizeof(Bbuf.mtype),0) < 0)
{
perror("msgsnd");
return -1;
}
if(strcmp(Bbuf.mtext,"quit")==0)
break;
}
}
else if(0 == cpid) //子进程(发送),B终端发送消息,A终端接收
{
while(1)
{
msgrcv(msqid,&Bbuf,sizeof(Bbuf.mtext),1,0);
if(res < 0)
{
perror("msgrcv");
return -1;
}
if(strcmp(Bbuf.mtext,"quit")==0)
break;
printf("%s\n",Bbuf.mtext);
}
kill(getppid(),2);
}
else
{
perror("fork");
return -1;
}
return 0;
}
3)结果
作业二:使用共享内存实现A进程打印字符串,B进程逆置字符串,打印结果为【正序 逆序 正序 逆序】
打开两个终端,要求实现:
- 在共享内存中存入字符串 “1234567”
- A进程循环打印字符串,B进程循环倒置字符串,要求结果不允许出现乱序
- 提示:共享内存中存储 flag + string.
1)程序
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
//创建key值
key_t key = ftok("./",10);
if(key < 0)
{
perror("ftok");
return -1;
}
printf("key = %#x\n",key);
//创建共享内存,获得shmid号
int shmid = shmget(key,32,IPC_CREAT|0664);
if(shmid < 0)
{
perror("shmget");
return -1;
}
printf("shmid = %d\n",shmid);
//映射共享内存到用户空间
void* addr= shmat(shmid,NULL,0);
if((void*)-1 == addr)
{
perror("shmat");
return -1;
}
printf("addp = %p",addr);
*(int*)addr=0;
//strcat((char*)addr+4,"1234567");
char *ptr=(char*)addr+4;
strcpy(ptr,"1234567");
pid_t cpid = fork();
if(cpid > 0) //父进程:打印
{
while(1)
{
if(0 == *(int*)addr)
{
printf("%s\n",(char*)addr+4);
*(int*)addr=1;
}
}
}
else if(0 == cpid) //子进程:逆置
{
char t;
while(1)
{
if(1 == *(int*)addr)
{
char *p=(char*)addr+4;
char *q=(char*)addr+4+strlen(ptr)-1;
while(p<q)
{
t=*p;
*p=*q;
*q=t;
p++;
q--;
}
*(int*)addr=0;
}
}
}
else
{
perror("fork");
return -1;
}
return 0;
}
2)结果