一:任务描写叙述

A,B两个进程通过管道通信,像曾经的互相聊天一样,然后A进程每次接收到的数据通过A1进程显示(一个新进程,用于显示A接收到的信息),A和A1间的数据传递採用共享内存,相应的有一个B1进程。用于显示B进程接收到的信息。

针对A,B进程,退出时採用ctrl+c退出,当收到相应信号后。自身进程可以通过信号处理函数进行资源清理,清理后exit退出进程。(A1,B1,手动关闭就可以)。界面图例如以下。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

二:代码展示

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>

三:结果显示

撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)的更多相关文章

  1. Linux环境进程间通信: 共享内存

    Linux环境进程间通信: 共享内存 第一部分 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进 ...

  2. Linux系统编程之命名管道与共享内存

    在上一篇博客中,我们已经熟悉并使用了匿名管道,这篇博客我们将讲述进程间通信另外两种常见方式--命名管道与共享内存. 1.命名管道 管道是使用文件的方式,进行进程之间的通信.因此对于管道的操作,实际上还 ...

  3. Linux信号量同步共享内存实验.

    Linux信号量同步共享内存实验. Linux信号量同步共享内存实验. 简述 程序流程 信号量和共享内存的系统函数 信号量系统函数及接口 共享内存系统函数及接口 写程序 读程序 简述 本文主要内容是自 ...

  4. Linux IPC之共享内存C 事例

    Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报  分类: Linux(3)  读书札记(3)  版权 ...

  5. Linux进程间通信—使用共享内存

    Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内 ...

  6. Linux IPC POSIX 共享内存

    模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...

  7. linux进程间通信之共享内存篇

    本文是对http://www.cnblogs.com/andtt/articles/2136279.html中共享内存(上)的进一步阐释说说明 1 共享内存的实现原理 共享内存是linux进程间通讯的 ...

  8. Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字

    Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...

  9. Linux进程间通信(四) - 共享内存

    共享内存的优势 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只 ...

随机推荐

  1. 经验之谈—让你看明确block

    事实上我感觉不常常使用block的朋友.对block应该是比較陌生的,那么如今我们来扒开block的真面目,看看block的本质 普通的局部变量.block内部仅仅会引用它初始的值(block定义那一 ...

  2. Word Ladder II [leetcode]

    本题有几个注意点: 1. 回溯找路径时.依据路径的最大长度控制回溯深度 2. BFS时,在找到end单词后,给当前层做标记find=true,遍历完当前层后结束.不须要遍历下一层了. 3. 能够将字典 ...

  3. Dcloud课程8 开心一刻应用如何实现

    Dcloud课程8 开心一刻应用如何实现 一.总结 一句话总结:app就是远程调用接口获得数据,我们在后台要做的,就是写一个个让页面获得接口的数据.这里用的是公共笑话接口. 1.ajax返回给页面的h ...

  4. Logstash之Logstash inputs(file和redis插件)、Logstash outputs(elasticsearch 和redis插件)和Filter plugins

     前期博客 Logstash安装和设置(图文详解)(多节点的ELK集群安装在一个节点就好) Filebeat啊,根据input来监控数据,根据output来使用数据!!! 请移步, Filebeat之 ...

  5. Linux下基于LDAP统一用户认证的研究

    Linux下基于LDAP统一用户认证的研究                   本文出自 "李晨光原创技术博客" 博客,谢绝转载!

  6. Java学习笔记三

    1.面向过程思想,强调的是过程(即动作,函数):面向对象思想,强调的是对象. 2.类与对象关系:类是对事物的描述(属性和行为-方法),对象是类的实例.对象通过new生成.属性也称成员变量;方法也称成员 ...

  7. ArcGIS小技巧——多图层情况下交互显示效果

    在使用ArcMap处理数据的过程中,通常需要对比不同图层之间的差异.或者查看影像配准情况,这时我通常会怀念ENVI中的强大的拉幕显示.闪烁.亮度和透明度显示工具...... 直到有一天,闲着没事干捣鼓 ...

  8. 1.2 Use Cases中 Log Aggregation官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ Log Aggregation 日志聚合 Many people use Kafka ...

  9. 【Codeforces Round #447 (Div. 2) B】Ralph And His Magic Field

    | [链接] 我是链接,点我呀:) [题意] 给你一个n*m矩阵,让你在里面填数字. 使得每一行的数字的乘积都为k; 且每一列的数字的乘积都为k; k只能为1或-1 [题解] 显然每个位置只能填1或- ...

  10. Validation failed for query for method public abstract boxfish.bean.Student boxfish.service.StudentServiceBean.find(java.lang.String)!

    转自:https://blog.csdn.net/lzx925060109/article/details/40323741 1. Exception in thread "main&quo ...