linux下实现两人、三人无序对话功能
序:引子
对话功能实际上就是利用管道见得通信。最原始的是一方发另一方收,不能进项交互,发送方的代码如下:
/*============================================
> Copyright (C) 2014 All rights reserved.
> FileName:send.c
> author:donald
> details:
==============================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 1024
int main(int argc, const char *argv[])
{ if(- == mkfifo(argv[],)){//creat 2
perror("failed");
exit(-);
} printf("mkfifo over!\n");
int fd_send,fd_recev;
printf("open fifo...\n"); fd_send = open(argv[],O_WRONLY); if(fd_send == -){//必须另一方打开
perror("open failed");
unlink(argv[]);
exit(-);
}
printf("open success!\n"); char send_buf[N];
while(memset(send_buf,,N),fgets(send_buf,N,stdin) != NULL){
write(fd_send,send_buf,strlen(send_buf));
} printf("send over\n");
unlink(argv[]);
return ;
}
send.c
接收方的代码:
/*============================================
> Copyright (C) 2014 All rights reserved.
> FileName:recv.c
> author:donald
> details:
==============================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 1024
int main(int argc, const char *argv[])
{
int fd_send,fd_recev;
printf("open fifo...\n");
fd_recev = open(argv[],O_RDONLY); if(fd_send == -){
perror("open failed");
unlink(argv[]);
exit(-);
}
printf("open success!\n"); char recev_buf[];
while(memset(recev_buf,,N),read(fd_recev,recev_buf,N) > ){
printf("%s",recev_buf);
} printf("recev over\n");
close(fd_recev);
unlink(argv[]);
return ;
}
recev.c
两人回话
对于两个程序之间的进行交互式对话有两种方式:
A.一问一答式,这是最简单的方式,但也是最不人性化的方法,运行后你就会产生一种回到上个世纪的错觉
B.没有固定的顺序,和QQ一样,想说就说,不用等到另一方说完一句才能说。
A方法比较简单,直接上代码:
启动方:
/*============================================
> Copyright (C) 2014 All rights reserved.
> FileName:send.c
> author:donald
> date:2014/08/22/ 14:45:45
> details:
==============================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 1024
int main(int argc, const char *argv[])
{ if(- == mkfifo(argv[],)){//creat 1
perror("failed");
exit(-);
} printf("mkfifo over!\n");
int fd_send,fd_recev;
printf("open fifo...\n"); fd_send = open(argv[],O_WRONLY); if(fd_send == -){//必须另一方打开
perror("open failed");
unlink(argv[]);
// exit(-1);
}
printf("open success!\n"); char send_buf[N];
while(memset(send_buf,,N),fgets(send_buf,N,stdin) != NULL){
write(fd_send,send_buf,strlen(send_buf));
} printf("send over\n");
unlink(argv[]);
return ;
}
send.c
B方法利用创建一个进程(fork)来实现交互,其代码为:
/*===========================================
> Copyright (C)2014All rights reserved
> File Name: fork_re_se.c
> Author: Donald
=============================================*/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 1024
int main(int argc, const char *argv[])
{
#if 1
if(- == mkfifo(argv[],)){
perror("failed");
exit(-);
}
printf("mkfifo over!\n");
#endif
int fd_send,fd_recev;
printf("open fifo...\n");
fd_recev = open(argv[],O_RDONLY);
fd_send = open(argv[],O_WRONLY); if(fd_send == - || fd_recev == -){
perror("open failed");
unlink(argv[]);
exit(-);
}
printf("open success!\n"); char recev_buf[];
char send_buf[N];
if(fork() == ){//child recev
close(fd_send);
//while(memset(recev_buf,0,N),read(fd_recev,recev_buf,strlen(recev_buf)) != 0){这里不能用strlen(recev_buf在while中进行了初始化,所以长度为0)
while(memset(recev_buf,,N),read(fd_recev,recev_buf,N) != ){
//write(1,recev_buf,N);
printf("%s",recev_buf);
}
exit();
}else{//parent send
close(fd_recev);
while(memset(send_buf,,N),fgets(send_buf,N,stdin) != NULL){
write(fd_send,send_buf,strlen(send_buf));
}
close(fd_send);
wait(NULL);
unlink(argv[]);
}
printf("recev over\n");
return ;
}
fork_re_se.c
/*===========================================
> Copyright (C)2014All rights reserved
> File Name: fork_se_re.c
> Author: Donald
=============================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 1024
int main(int argc, const char *argv[])
{
#if 1
if(- == mkfifo(argv[],)){
perror("failed");
exit(-);
}
printf("mkfifo over!\n");
#endif
int fd_send,fd_recev;
printf("open fifo...\n");
fd_send = open(argv[],O_WRONLY);
fd_recev = open(argv[],O_RDONLY); if(fd_send == - || fd_recev == -){
perror("open failed");
unlink(argv[]);
exit(-);
}
printf("open success!\n"); char recev_buf[];
char send_buf[N];
if(fork() == ){//child recev
close(fd_send);
while(memset(recev_buf,,N),read(fd_recev,recev_buf,N) != ){
//write(1,recev_buf,N);
printf("%s",recev_buf);
}
exit();
}else{//parent send
close(fd_recev);
while(memset(send_buf,,N),fgets(send_buf,N,stdin) != NULL){
write(fd_send,send_buf,strlen(send_buf));
}
close(fd_send);
wait(NULL);
unlink(argv[]);
} printf("send over\n");
return ;
}
fork_se_re.c
三人无序对话
本程序主要通过父进程创建两个子进程,通过管道来实现,和两人无序对话的功能一样。只要逻辑清晰,并不难。共需要pipe(有名管道)六根,功能为用于读、写,为了使逻辑清晰,方便讨论,以下1、2、3分别代表程序1、2、3之间的管道,分别对程序之间的管道进项讨论分析:
| A | B | C | |||
| 1-2 | write | 1-2 | read | 1-3 | read |
| 1-3 | write | 2-1 | write | 3-1 | write |
| 2-1 | read | 2-3 | write | 2-3 | read |
| 3-1 | read | 3-2 | read | 3-2 | write |
- A:第一人
/*============================================
> Copyright (C) 2014 All rights reserved.
> FileName:1.c
> author:donald
> date:2014/08/22/ 20:28:53
> details:
==============================================*/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 1024
int main(int argc, const char *argv[])//12,13,21,31
{
if(mkfifo(argv[],) == - || mkfifo(argv[],) == -){
perror("mkfifo");
exit();
} int fd_12,fd_13,fd_21,fd_31;
char buf[N];
fd_12 = open(argv[],O_WRONLY);
fd_13 = open(argv[],O_WRONLY);
fd_21 = open(argv[],O_RDONLY);
fd_31 = open(argv[],O_RDONLY); printf("open sucess\n"); if(fork() == ){//21 r
close(fd_13);
close(fd_12);
close(fd_31);
while(memset(buf,,N),read(fd_21,buf,N) != ){
printf("from 2:");
write(,buf,strlen(buf));
}
close(fd_21);
exit();
}
if(fork() == ){//31 r
close(fd_13);
close(fd_12);
close(fd_21);
while(memset(buf,,N),read(fd_31,buf,N) != ){
printf("from 3:");
write(,buf,strlen(buf));
}
close(fd_31);
exit();
} //12 13 w
close(fd_21);
close(fd_31);
while(memset(buf,,N),fgets(buf,N,stdin) != NULL){
write(fd_13,buf,strlen(buf));
write(fd_12,buf,strlen(buf));
}
close(fd_13);
close(fd_12);
wait(NULL);
wait(NULL); unlink(argv[]);
unlink(argv[]);
printf("program 1 over\n");
return ;
}
1.c
- B:第二人
/*============================================
> Copyright (C) 2014 All rights reserved.
> FileName:2.c
> author:donald
> date:2014/08/22/ 20:29:02
> details:
==============================================*/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 1024
int main(int argc, const char *argv[])
{ if(mkfifo(argv[],) == - || mkfifo(argv[],) == -){
perror("mkfifo");
exit();
} int fd_12,fd_21,fd_23,fd_32;
char buf[N];
fd_12 = open(argv[],O_RDONLY);
fd_21 = open(argv[],O_WRONLY);
fd_23 = open(argv[],O_WRONLY);
fd_32 = open(argv[],O_RDONLY); printf("open success\n"); if(fork() == ){//12 r
close(fd_32);
close(fd_21);
close(fd_23);
while(memset(buf,,N),read(fd_12,buf,N) != ){
printf("from 1:");
write(,buf,strlen(buf));
}
close(fd_12);
exit();
} if(fork() == ){//32 r
close(fd_12);
close(fd_21);
close(fd_23);
while(memset(buf,,N),read(fd_32,buf,N) != ){
printf("from 3:");
write(,buf,strlen(buf));
}
close(fd_32);
exit();
} //21 23 w
close(fd_12);
close(fd_32);
while(memset(buf,,N),fgets(buf,N,stdin) != NULL){
write(fd_21,buf,strlen(buf));
write(fd_23,buf,strlen(buf));
}
close(fd_21);
close(fd_23);
wait(NULL);
wait(NULL); unlink(argv[]);
unlink(argv[]);
printf("program 2 over\n");
return ;
}
2.c
- C:第三人
/*============================================
> Copyright (C) 2014 All rights reserved.
> FileName:3.c
> author:donald
> date:2014/08/22/ 20:29:13
> details:
==============================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 1024
int main(int argc, const char *argv[])
{ if(mkfifo(argv[],) == - || mkfifo(argv[],) == -){
perror("mkfifo");
exit();
} int fd_13,fd_31,fd_23,fd_32;
char buf[N];
fd_13 = open(argv[],O_RDONLY);
fd_31 = open(argv[],O_WRONLY);
fd_23 = open(argv[],O_RDONLY);
fd_32 = open(argv[],O_WRONLY); printf("open success\n"); if(fork() == ){//13 r
close(fd_31);
close(fd_23);
close(fd_32);
while(memset(buf,,N),read(fd_13,buf,N) != ){
printf("from 1:");
write(,buf,strlen(buf));
}
close(fd_13);
exit();
}
if(fork() == ){//23 r
close(fd_13);
close(fd_31);
close(fd_32);
while(memset(buf,,N),read(fd_23,buf,N) != ){
printf("from 2:");
write(,buf,strlen(buf));
}
close(fd_23);
exit();
} //31 32 w
close(fd_13);
close(fd_23);
while(memset(buf,,N),fgets(buf,N,stdin) != NULL){
write(fd_31,buf,strlen(buf));
write(fd_32,buf,strlen(buf));
}
close(fd_31);
close(fd_32);
wait(NULL);
wait(NULL); unlink(argv[]);
unlink(argv[]);
printf("program 3 over\n");
return ;
}
3.c
PS:在命令行参数中还需注意的,假设1.c、2.c、3.c的可执行文件为A.out、B.out、C.out。命令行参数分别为:(其实和表格里分析的一样)
- ./A.out 12.fifo 13.fifo 21.fifo 31.fifo
- ./B.out 12.fifo 21.fifo 23.fifo 32.fifo
- ./C.out 13.fifo 31.fifo 23.fifo 32.fifo
三人以上的用fork就没必要了,需要另寻方,一般采用服务器的处理方式。
linux下实现两人、三人无序对话功能的更多相关文章
- Linux 下启动两个tomcat
Linux 下启动两个tomcat 闲来无事学习nginx,想要配置个load balance.可是先决条件是:得有两个web容器.两个电脑是不用想了.只能想办法在一个机器上启动两个tomcat.原以 ...
- Linux下配置两个或多个Tomcat启动
Linux下配置两个或多个Tomcat启动 (2012-08-14 11:59:31) 转载▼ 标签: 杂谈 分类: linux_tomcat 步骤如下: (1)修改/etc/profile文件.添加 ...
- rlwrap: command not found和解决linux下sqlplus 提供浏览历史命令行的功能
rlwrap工具可以解决linux下sqlplus 提供浏览历史命令行的功能,和删除先前输入错误的字母等问题 1.安装 需要readline包 这个安装光盘就有 [root@asm RedHat]# ...
- Linux下的两种磁盘分区工具的使用
如何使用fdisk和parted分区工具来进行硬盘分区,下面我来说一下在Linux系统中这两种硬盘分区工具的使用方法: ----------fdisk分区工具---------- ...
- Linux下使用两个线程协作完成一个任务的简易实现
刚解决了之前的那个Linux下Pthread库的问题,这次就来使用两个线程来协作,共同完成一个求和的任务. 打一下基础吧 本次需要使用到的知识点有: lpthread,编译的时候用到,相当于一个声明的 ...
- Linux 下的两种分层存储方案
背景介绍 随着固态存储技术 (SSD),SAS 技术的不断进步和普及,存储介质的种类更加多样,采用不同存储介质和接口的存储设备的性能出现了很大差异.SSD 相较于传统的机械硬盘,由于没有磁盘的机械转动 ...
- Linux下的两个经典宏定义 转
http://www.linuxidc.com/Linux/2016-08/134481.htm http://www.linuxidc.com/Linux/2013-01/78003.htm htt ...
- Linux下的两个经典宏定义【转】
转自:http://www.linuxidc.com/Linux/2015-07/120014.htm 本文首先介绍Linux下的经典宏定义,感受极客的智慧,然后根据该经典定义为下篇文章作铺垫. of ...
- Linux下性能监控的三把军刀
Linux主机怎么管,十八般兵器件件都可以算得上是瑞士军刀,称手的兵器一两件即可,最常用的,莫过于stat家族三兄弟吧. 计算机主要资源是什么?CPU.内存和磁盘?尽管现在云计算技术有多普及,查看一个 ...
随机推荐
- const参数,const返回值与const函数
在C++程序中,经常用const 来限制对一个对象的操作,例如,将一个变量定义为const 的: const int n=3; 则这个变量的值不能被修改,即不能对变量赋值. const 这个关键字 ...
- GDAL 生成shp文件
附件:http://pan.baidu.com/s/1i3GPwrV(C#版GDAL接口.dll) 示例程序: http://pan.baidu.com/s/1jpIKQ (程序是在vs2008 x ...
- ORACLE DUAL表详解 .
今天在戴明明同学的QQ空间里看到篇不错的关于DUAL表的文章,自己平时也时而会用到,可是没有系统的学习过,借这个机会学习学习~ ==================================== ...
- PowerDesigner中NAME和COMMENT的互相转换,需要执行语句
原文: http://www.cnblogs.com/xnxylf/p/3288718.html 由于PDM 的表中 Name 会默认=Code 所以很不方便, 所以需要将 StereoType 显示 ...
- (2012年旧文)纪念史蒂夫乔布斯---IT界的普罗米修斯
谈苹果与乔布斯系列一 IT界的普罗米修斯 纪念PC界的先驱 史蒂夫乔布斯 2012-4-5 清明节,纪念IT时代的开创人—伟大的史蒂夫 乔布斯. 没有乔布斯,计算机还是属于一群科技人士的工具,没有漂 ...
- 实现一个Memcpy函数:将源指针所指的区域从起始地址开始的n个字节复制到目的指针所指区域
首先肯定要先看看这两部分是不是有内存重叠?为什么? 1.因为如果有内存重叠(目的地址起始位置处于源指针所指区域之中),你再从起始位置复制的话,这样目的地址改变的时候将源地址内存里面存的东西给改变了,所 ...
- MySQL query_cache_type 详解
MySQL设置查询缓存的用意: 把查询到的结果缓存起来,下次再执行相同查询时就可以直接从结果集中取:这样就比重新查一遍要快的多. 查询缓存的最终结果是事与愿违: 之所以查询缓存并没有能起到提升性能的做 ...
- SQL Server 备份的 8 种方法。
方法 1. 完整备份 方法 2. 差异备份 方法 3. 部分备份(备份数据库的read_write部分) 方法 4. 文件备份 方法 5. 文件组备份 方法 6. 只复制备份 方法 7. 日志备份 - ...
- Jquery一个slideToggle搞定div的隐藏与显示
Jquery一个slideToggle搞定div的隐藏与显示 <!DOCTYPE html> <html> <head> <script src=" ...
- 全选demo
我们处理数据时,最好能够支持全选操作. 选中之后,进行删除,或其他处理. 我自己写了一个demo. 主要功能: 1.点击全部选中 2.点击全部取消 3.然后进行获取选中的id,进行处理 代码如下: & ...