-
2021-05-18 03:14:37
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
linux有名管道通信实验
分享到:
本文关键字: 有名管道,linux有名管道 1.实验目的 通过编写有名管道多路通信实验,进一步掌握管道的创建、读写等操作,同时复习使用select()函数实现管道的通信。 2.实验内容 这里采用管道函数创建有名管道(并不是在控制台下输入命令),而且使用select()函数替代poll()函数实现多路复用(使用select()函数是出于以演示为目的)。 3.实验步骤 (1)画出流程图。该实验流程图如图1所示。图1 实验流程图 (2)编写代码。该实验源代码如下: /* pipe_select.c */ #include #include #include #include #include #include #include #define FIFO1 "in1" #define FIFO2 "in2" #define MAX_BUFFER_SIZE 1024 /* 缓冲区大小 */ #define IN_FILES 3 /* 多路复用输入文件数目 */ #define TIME_DELAY 60 /* 超时值秒数 */ #define MAX(a, b) ((a > b)?(a):(b)) int main(void) { int fds[IN_FILES]; char buf[MAX_BUFFER_SIZE]; int i, res, real_read, maxfd; struct timeval tv; fd_set inset,tmp_inset; fds[0] = 0; /* 创建两个有名管道 */ if (access(FIFO1, F_OK) == -1) { if ((mkfifo(FIFO1, 0666) < 0) && (errno != EEXIST)) { printf("Cannot create fifo file\n"); exit(1); } } if (access(FIFO2, F_OK) == -1) { if ((mkfifo(FIFO2, 0666) < 0) && (errno != EEXIST)) { printf("Cannot create fifo file\n"); exit(1); } } /* 以只读非阻塞方式打开两个管道文件 */ if((fds[1] = open (FIFO1, O_RDONLY|O_NONBLOCK)) < 0) { printf("Open in1 error\n"); return 1; } if((fds[2] = open (FIFO2, O_RDONLY|O_NONBLOCK)) < 0) { printf("Open in2 error\n"); return 1; } /* 取出两个文件描述符中的较大者 */ maxfd = MAX(MAX(fds[0], fds[1]), fds[2]); /* 初始化读集inset,并在读文件描述符集中加入相应的描述集 */ FD_ZERO(&inset); for (i = 0; i < IN_FILES; i++) { FD_SET(fds[i], &inset); } FD_SET(0, &inset); tv.tv_sec = TIME_DELAY; tv.tv_usec = 0; /* 循环测试该文件描述符是否准备就绪,并调用select()函数对相关文件描述符做相应操作* / while(FD_ISSET(fds[0],&inset) || FD_ISSET(fds[1],&inset) || FD_ISSET(fds[2], &inset)) { /* 文件描述符集的备份,以免每次都进行初始化 */ tmp_inset = inset; res = select(maxfd + 1, &tmp_inset, NULL, NULL, &tv); switch(res) { case -1: { printf("Select error\n"); return 1; } break; case 0: /* Timeout */ { printf("Time out\n"); return 1; } break; default: { for (i = 0; i < IN_FILES; i++) { if (FD_ISSET(fds[i], &tmp_inset)) { memset(buf, 0, MAX_BUFFER_SIZE); real_read = read(fds[i], buf, MAX_BUFFER_SIZE); if (real_read < 0) { if (errno != EAGAIN) { return 1; } } else if (!real_read) { close(fds[i]); FD_CLR(fds[i], &inset); } else { if (i == 0) { /* 主程序终端控制 */ if ((buf[0] == 'q') || (buf[0] == 'Q')) { return 1; } } else { /* 显示管道输入字符串 */ buf[real_read] = '\0'; printf("%s", buf); } } } /* end of if */ } /* end of for */ } break; } /* end of switch */ } /* end of while */ return 0; } (3)编译并运行该程序。 (4)另外打开两个虚拟终端,分别输入“cat > in1”和“cat > in2”,接着在该管道中输入相关内容,并观察实验结果。 4.实验结果 实验运行结果如下: $ ./pipe_select (必须先运行主程序) SELECT CALL select call TEST PROGRAMME test programme END end q /* 在终端上输入“q”或“Q”立刻结束程序运行 */ $ cat > in1 SELECT CALL TEST PROGRAMME END $ cat > in2 select call test programme end 本文选自华清远见嵌入式培训教材《从实践中学嵌入式Linux应用程序开发》
更多相关内容 -
操作系统实验四 进程的管道通信 实验报告
2018-10-23 10:52:07编写一段程序,实现进程的管道通信。 使用系统调用pipe( )建立一条管道,创建两个子进程P1和P2。让P1和P2分别向管道各写一句话: child process P1 is sending messages! child process P2 is sending messages! 父... -
线程和进/线程管道通信实验(操作系统实验报告二)
2014-08-06 14:34:48通过 Linux 系统中线程和管道通信机制的实验,加深对于线程控制和管道通信概念的理解,观察和体验并发进/线程间的通信和协作的效果 ,练习利用无名管道进行进/线程间通信的编程和调试技术 -
管道通信实验
2014-12-11 21:36:31对于进程间的通信有很多种,而管道通信就是其中一个,这篇文章就是基于这种需要做的通信实验 -
进程的管道通信 实验报告
2011-11-03 11:20:18编写程序实现进程的管道通信。用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话: Child 1 is sending a message! Child 2 is sending a message! 父进程从管道中读出二个来自子进程的信息并... -
进程间通信之管道通信实验内容分析
2021-05-17 14:29:02标签:操作系统(344)Linux(1563)8.7.1 管道通信实验1.实验目的通过编写有名管道多路通信实验,读者可进一步掌握管道的创建、读写等操作,同时,也复习使用select()函数实现管道的通信。2.实验内容读者还记得在...标签:操作系统(344)Linux(1563)
8.7.1 管道通信实验
1.实验目的
通过编写有名管道多路通信实验,读者可进一步掌握管道的创建、读写等操作,同时,也复习使用select()函数实现管道的通信。
2.实验内容
读者还记得在6.3.3小节中,通过mknod命令创建两个管道的实例吗?本实例只是在它的基础上添加有名管道的创建,而不用再输入mknod命令。
3.实验步骤
(1)画出流程图。
该实验流程图如图8.9所示。
图8.9 8.6.1实验流程图
(2)编写代码。
该实验源代码如下所示。
/* pipe_select.c*/
#include 《fcntl.h》
#include 《stdio.h》
#include 《unistd.h》
#include 《stdlib.h》
#include 《string.h》
#include 《TIme.h》
#include 《errno.h》
#define FIFO1 “in1”
#define FIFO2 “in2”
#define MAX_BUFFER_SIZE 1024 /* 缓冲区大小*/
#define IN_FILES 3 /* 多路复用输入文件数目*/
#define TIME_DELAY 60 /* 超时值秒数 */
#define MAX(a, b) ((a 》 b)?(a):(b))
int main(void)
{
int fds[IN_FILES];
char buf[MAX_BUFFER_SIZE];
int i, res, real_read, maxfd;
struct TImeval tv;
fd_set inset,tmp_inset;
fds[0] = 0;
/* 创建两个有名管道 */
if (access(FIFO1, F_OK) == -1)
{
if ((mkfifo(FIFO1, 0666) 《 0) && (errno != EEXIST))
{
printf(“Cannot create fifo file\n”);
exit(1);
}
}
if (access(FIFO2, F_OK) == -1)
{
if ((mkfifo(FIFO2, 0666) 《 0) && (errno != EEXIST))
{
printf(“Cannot create fifo file\n”);
exit(1);
}
}
/* 以只读非阻塞方式打开两个管道文件 */
if((fds[1] = open (FIFO1, O_RDONLY|O_NONBLOCK)) 《 0)
{
printf(“Open in1 error\n”);
return 1;
}
if((fds[2] = open (FIFO2, O_RDONLY|O_NONBLOCK)) 《 0)
{
printf(“Open in2 error\n”);
return 1;
}
/*取出两个文件描述符中的较大者*/
maxfd = MAX(MAX(fds[0], fds[1]), fds[2]);
/*初始化读集合inset,并在读文件描述符集合中加入相应的描述集*/
FD_ZERO(&inset);
for (i = 0; i 《 IN_FILES; i++)
{
FD_SET(fds[i], &inset);
}
FD_SET(0, &inset);
tv.tv_sec = TIME_DELAY;
tv.tv_usec = 0;
/*循环测试该文件描述符是否准备就绪,并调用select()函数对相关文件描述符做相应操作*/
while(FD_ISSET(fds[0],&inset)
|| FD_ISSET(fds[1],&inset) || FD_ISSET(fds[2], &inset))
{
/* 文件描述符集合的备份, 免得每次进行初始化 */
tmp_inset = inset;
res = select(maxfd + 1, &tmp_inset, NULL, NULL, &tv);
switch(res)
{
case -1:
{
printf(“Select error\n”);
return 1;
}
break;
case 0: /* Timeout */
{
printf(“Time out\n”);
return 1;
}
break;
default:
{
for (i = 0; i 《 IN_FILES; i++)
{
if (FD_ISSET(fds[i], &tmp_inset))
{
memset(buf, 0, MAX_BUFFER_SIZE);
real_read = read(fds[i], buf, MAX_BUFFER_SIZE);
if (real_read 《 0)
{
if (errno != EAGAIN)
{
return 1;
}
}
else if (!real_read)
{
close(fds[i]);
FD_CLR(fds[i], &inset);
}
else
{
if (i == 0)
{/* 主程序终端控制 */
if ((buf[0] == ‘q’) || (buf[0] == ‘Q’))
{
return 1;
}
}
else
{/* 显示管道输入字符串 */
buf[real_read] = ‘\0’;
printf(“%s”, buf);
}
}
} /* end of if */
} /* end of for */
}
break;
} /* end of switch */
} /*end of while */
return 0;
}
(3)编译并运行该程序。
(4)另外打开两个虚拟终端,分别键入“cat 》 in1”和“cat 》 in2”,接着在该管道中键入相关内容,并观察实验结果。
4.实验结果
实验运行结果与第6章的例子完全相同。
$ 。/pipe_select (必须先运行主程序)
SELECT CALL
select call
TEST PROGRAMME
test programme
END
end
q /* 在终端上输入’q’或’Q’立刻结束程序运行 */
$ cat 》 in1
SELECT CALL
TEST PROGRAMME
END
$ cat 》 in2
select call
test programme
end
-
实验四:Linux下进程管道通信.docx
2021-04-13 13:27:59操作系统实验四:Linux下进程管道通信 任务1:使用Pipe创建管道,创建一个子进程,子进程向父进程发送消息“I am your son!”,父进程接收到子进程的消息后,显示在屏幕上,并向子进程发送“I am your father!”。子... -
Linux管道通信(附实验报告)(附源代码)
2018-03-07 15:56:16编写程序实现进程的管道通信。用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话: Child 1 is sending a message! Child 2 is sending a message! 父进程从管道中读出二个来自子进程的信息并... -
实验一 进程通信——管道和信号实验报告.doc
2021-05-13 13:58:354.(4)进程的管道通信 编写程序,创建两个子进程。当此程序运行时,系统中有一个父进程和两个子进程。父进程在屏幕上显示“Parent”,子进程分别在屏幕上显示“Child1”和“Child2”。 如果在程序中使用系统调用... -
linux中管道通信实验
2019-10-18 18:17:21在linux内核中,fork函数用于创建进程 系统调用格式: pid=fork() fork()返回值的意义: 0 在子进程中,pid变量保存的fork()返回值为0,表示当前进程是子进程。 当大于0 在父进程中,pid变量保存的fork()返回值为子...在linux内核中,fork函数用于创建进程
系统调用格式:
pid=fork()
fork()返回值的意义:
0 在子进程中,pid变量保存的fork()返回值为0,表示当前进程是子进程。
当大于0 在父进程中,pid变量保存的fork()返回值为子进程的id值(进程唯一标识符)
-1 创建失败lockf函数用于对进程进行上锁和解锁,这就相当于PV操作,对共有资源进行限制。
参数定义
int lockf(files,function,size)
int files,function;
long size;
其中files是文件描述符,function是锁定和解锁,1表示锁定,0表示解锁,size是锁定或解锁的字节数,若用0,表示从文件的当前位置到文件尾。while((pid1=fork()==-1);
这句话的意思是当进程创建失败的时候,我们知道fork()返回值为-1代表创建失败,我们继续进行创建,直到进程创建成功。lockf(fd[1],1,0)
这句话就意味着在向fd[1]这个位置输入字符前对它进行锁定
与此相对应的
lockf(fd[1],0,0)
这句话意味着解锁。#include<unistd.h> #include<signal.h> #include<stdio.h> int pid1,pid2; main() { int fd[2]; char buf_out[100],buf_in[100]; pipe(fd); while((pid1=fork())==-1); if(pid1==0) { lockf(fd[1],1,0); strcpy(buf_out,"child P1 process is sending message!"); write(fd[1],buf_out,50); sleep(5); lockf(fd[1],0,0); exit(0); } else { while((pid2=fork())==-1); if(pid2==0) { lockf(fd[1],1,0); sprintf(buf_out,"child%d process is sending message1",getpid()); write(fd[1],buf_out,50); sleep(5); lockf(fd[1],0,0); exit(0); } else { wait(0); read(fd[0],buf_in,50); printf("%s\n",buf_in); wait(0); read(fd[0],buf_in,50); printf("%s\n",buf_in); exit(0); } } } ~
-
linux C语言开发管道通信实例详解
2021-01-10 19:36:31linux C语言开发管道通信 Linux系统本身为进程间通信提供了很多的方式,比如说管道、共享内存、socket通信等。管道的使用十分简单,在创建了匿名管道之后,我们只需要从一个管道发送数据,再从另外一个管道接受... -
Linux进程间通信(九)---综合实验之有名管道通信实验
2021-05-17 23:08:49实验目的通过编写有名管道多路通信实验,进一步掌握管道的创建、读写等操作,同时复习使用select()函数实现管道的通信。实验内容这里采用管道函数创建有名管道(不是在控制台下输入命令mknod),而且使用select()函数...实验目的
通过编写有名管道多路通信实验,进一步掌握管道的创建、读写等操作,同时复习使用select()函数实现管道的通信。
实验内容
这里采用管道函数创建有名管道(不是在控制台下输入命令mknod),而且使用select()函数替代poll()函数实现多路复用。如果对管道通信的知识忘了的话,请看这篇博客:
实验步骤
实验流程图如下
本实验用到了一些函数,主要是FD_ISSET()函数是新的,其它的函数在开头的网址的链接博客中都可以找到。
源程序
pipe_select.c文件,如有需要,
实验步骤
将上述程序编译后,必须先运行该程序(即./pipe_select),然后再另外打开两个虚拟终端,分别进入你的pipe_select所在目录(一定要进入这个目录噢,否则程序没有结果),分别在两个虚拟终端输入“cat > in1”和"cat > in2",接着在管道中输入相关内容。执行结果如下图:
终端1
终端2
终端3
可以看到此时在当前文件夹下已经创建了两个管道
-
管道通信实验报告
2018-07-02 13:25:53掌握利用管道实现进程间通信的方法编写一段程序,实现进程的管道通信:1.使用系统调用pipe()建立一条管道线。两个子进程p1和p2分别向管道各写一句话: Child 1 is sending a message! Chile 2 is sending a ... -
操作系统实验二——线程和管道通信实验
2020-12-07 14:57:53实验内容: 设有⼆元函数 f(x, y) = f(x) + f(y) 其中: f(x) = f(x-1) * x (x >1) f(x) = 1 (x=1) f(y) = f(y-1) + f(y-2) (y > 2) f(y) = 1 (y=1, 2) 请编程建⽴ 3 个并发协作进程或线程,它们分别完成 f(x,... -
操作系统实验二:线程和管道通信实验
2019-04-21 11:29:37山东大学操作系统实验二:进程控制实验 #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <stdio.h> #include <fcntl.h> #include<stdlib.h... -
LINUX管道通信实验报告
2009-05-24 20:56:50LINUX 管道通信 实验报告(完整版) -
进程的管道通信实验
2011-12-24 17:39:17进程的管道通信实验 实验四 进程的管道通信实验 1、了解什么是管道 2、熟悉UNIX/LINUX支持的管道通信方式 1、了解什么是管道 2、熟悉UNIX/LINUX支持的管道通信方式 利用linux下的vi编辑器及GCC编辑工具完成实验 PC... -
操作系统进程的管道通信实验
2012-12-16 19:29:222、编写程序实现进程的管道通信。用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话: Child 1 is sending a message! Child 2 is sending a message! 父进程从管道中读出二个来自子进程的信息... -
Linux软中断通信实验报告_进程的软中断通信实验报告
2020-12-16 10:36:56实验2 Linux软中断通信 1.实验目的 通过本实验掌握软中断的基本原理掌握中断信号的使用进程的创建以及系统计时器的使用 2.实验内容上交的实验2统一取名为test2) 由父进程创建两个子进程通过终端输入Crtl+\组合键向父... -
Linux进程通信实验(管道通信)
2021-05-09 08:28:27上学期接触了linux系统,刚好操作系统课程的实验内容也都是要求在linux下完成,几个实验中个人认为对两个进程通信实验了解学习的比较好,所以这一篇和下一篇记录一下两个实验过程中的学习收获和实验成果。... -
linux管道实验,linux有名管道通信实验
2021-05-18 03:14:07该楼层疑似违规已被系统折叠隐藏此楼查看此楼linux有名管道通信实验分享到:本文关键字: 有名管道,linux有名管道 1.实验目的 通过编写有名管道多路通信实验,进一步掌握管道的创建、读写等操作,同时复习使用... -
实验3 进程的通信实验.docx
2020-12-18 21:54:30实验3 进程的通信实验.docx -
进程的管道通信实验 操作系统
2010-01-08 08:24:16操作系统课程设计之小题---进程的管道通信实验