一:任务描述
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); }
#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); }
#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>
三:结果显示
版权声明:本文为博主原创文章,未经博主允许不得转载。
撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)
原文地址:http://blog.csdn.net/bao2516090/article/details/46963685