一:任务描述
A,B两个进程通过管道通信,像以前的互相聊天一样,然后A进程每次接收到的数据通过A1进程显示(一个新进程,用于显示A接收到的信息),A和A1间的数据传递采用共享内存,对应的有一个B1进程,用于显示B进程接收到的信息。针对A,B进程,退出时采用ctrl+c退出,当收到对应信号后,自身进程能够通过信号处理函数进行资源清理,清理后exit退出进程。(A1,B1,手动关闭即可)。界面图如下。
二:代码展示
A进程
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
int shm_id;
struct t
{
char buf[128];
};
struct t *p;
void hanle(int sig)
{
shmdt(p);
shmctl(shm_id,IPC_RMID,NULL);//删除共享内存
printf("delete OK........\n");
exit(0);
}
int main()
{//A进程
signal(SIGINT,hanle);//捕捉 ctrl+c信号
shm_id=shmget((key_t)1234,4096,0600|IPC_CREAT);
//创建了一个共享内存
// struct t *p;
p=(struct t*)shmat(shm_id,NULL,0);//拿到内存的指针结构体
int f1;
f1=open("1.fifo",O_WRONLY);//对1 打开写端
int f2;
f2=open("2.fifo",O_RDONLY);//对2 打开读端
fd_set readset;
//定义了可读集合
int maxfd;
maxfd=STDIN_FILENO > f2 ? STDIN_FILENO+1:f2+1;
struct timeval check;
check.tv_sec=1;//设置查看时间是一秒
char buf[128];
while(1)
{
FD_ZERO(&readset);//初始化
FD_SET(STDIN_FILENO,&readset);//添加监控对象
FD_SET(f2,&readset);
select(maxfd,&readset,NULL,NULL,&check);//返回可读的监控对象
if(FD_ISSET(STDIN_FILENO,&readset))
{//如果监控到了1管道中有标准输入 那么获取到数据 写到管道中
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]='\0';
write(f1,buf,sizeof(buf));//写到管道1中
}
if(FD_ISSET(f2,&readset))
{//监控到了管道2中可以读
memset(buf,0,sizeof(buf));
read(f2,buf,sizeof(buf));//从管道2中读到buf了
strcpy(p->buf,buf);//将管道2中读到的buf 弄到共享内存
printf("from 2: %s\n",buf);
}
if(strcmp(buf,"bye")==0)
{
break;
}
}
exit(0);
}
B进程
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int shm_id;
struct t
{
char buf[128];
};
struct t *p;
void hanle(int sig)
{
shmdt(p);
shmctl(shm_id,IPC_RMID,NULL);//删除共享内存
printf("delete OK........\n");
exit(0);
}
int main()
{//B进程
signal(SIGINT,hanle);
shm_id=shmget((key_t)1235,4096,0600|IPC_CREAT);
// struct t *p;
p=(struct t*)shmat(shm_id,NULL,0);
int f1;
f1=open("1.fifo",O_RDONLY);//对1 打开读端
int f2;
f2=open("2.fifo",O_WRONLY);//对2 打开写端
fd_set readset;
//定义了可读集合
int maxfd;
maxfd=STDIN_FILENO > f1 ? STDIN_FILENO+1:f1+1;
struct timeval check;
check.tv_sec=1;//设置查看时间是一秒
char buf[128];
while(1)
{
FD_ZERO(&readset);//初始化
FD_SET(STDIN_FILENO,&readset);//添加监控对象
FD_SET(f1,&readset);
select(maxfd,&readset,NULL,NULL,&check);//返回可读的监控对象
if(FD_ISSET(STDIN_FILENO,&readset))
{//如果监控到了1管道中有标准输入 那么获取到数据 写到管道中
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]='\0';
write(f2,buf,sizeof(buf));//写到管道2中
}
if(FD_ISSET(f1,&readset))
{//监控到了管道2中可以读
memset(buf,0,sizeof(buf));
read(f1,buf,sizeof(buf));//从管道1中读
strcpy(p->buf,buf);//将读出的字符 放到共享内存中
printf("from 1: %s\n",buf);
}
if(strcmp(buf,"bye")==0)
{
break;
}
}
exit(0);
}
A1进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
int shm_id;
struct t
{
char buf[128];
};
struct t *p;
void hanle(int sig)
{
shmdt(p);
shmctl(shm_id,IPC_RMID,NULL);//删除共享内存
printf("delete OK........\n");
exit(0);
}
int main()
{
shm_id=shmget((key_t)1234,4096,0600|IPC_CREAT);
//获得了共享内存
// struct t *p;
p=(struct t*)shmat(shm_id,NULL,0);//这个也拿到了
char s[128]={0};
while(1)
{
if(strcmp(s,p->buf)!=0)
{//字符串不相同 那么就打印出来
strcpy(s,p->buf);
printf("from B :%s\n",p->buf);
}
}
exit(0);
}
B1进程
<span style="font-size:14px;">#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
int shm_id;
struct t
{
char buf[128];
};
struct t *p;
void hanle(int sig)
{
shmdt(p);
shmctl(shm_id,IPC_RMID,NULL);//删除共享内存
printf("delete OK........\n");
exit(0);
}
int main()
{
shm_id=shmget((key_t)1235,4096,0600|IPC_CREAT);
//获得了共享内存
// struct t *p;
p=(struct t*)shmat(shm_id,NULL,0);//这个也拿到了
char s[128]={0};
while(1)
{
if(strcmp(s,p->buf)!=0)
{//字符串不相同 那么就打印出来
strcpy(s,p->buf);
printf("from A :%s\n",p->buf);
}
}
exit(0);
}</span><span style="font-size:18px;">
</span>
三:结果显示