建设公司自己的网站首页,商标设计注册,个人网站展示,网络电商平台有哪些《Linux操作系统原理分析之Linux 进程管理 6》#xff08;10#xff09; 4 Linux 进程管理4.6 Linux 管道4.6.1 管道的概念4.6.2 无名管道1.终端使用2.程序中使用 4.6.2 命名管道1.终端使用2.程序中使用 4 Linux 进程管理
4.6 Linux 管道
4.6.1 管道的概念
1、管道是 linu… 《Linux操作系统原理分析之Linux 进程管理 6》10 4 Linux 进程管理4.6 Linux 管道4.6.1 管道的概念4.6.2 无名管道1.终端使用2.程序中使用 4.6.2 命名管道1.终端使用2.程序中使用 4 Linux 进程管理
4.6 Linux 管道
4.6.1 管道的概念
1、管道是 linux 进程通信的一种手段 2、管道通信时一端写管道进程另一端读管道进程获取数据。 3、管道本质是共享文件。 4、管道以文件系统为基础实现。 5、数据在管道中先进先出方式以字符流形态传送。 管道分两种无名管道、命名管道。它们的内部结构是一致的但是用方式不同。 无名管道只能在父子进程之间通信 命名管道可以在任意进程间通信。 4.6.2 无名管道
linux 管道可以在终端的命令行中使用也可以在程序中使用。
1.终端使用
无名管道连接两个命令如下命令中“|”就是管道
$ls –l | more 2.程序中使用
在程序设计中无名管道的建立由系统调用 pipe实现其定义
#include unstd.h
Int pipe(int filedes[2]);其中 filedes[]是具有两个元素的 int 型数组。在调用 pipe建立一个无名管道后使用两个文件标识号来表示管道的两端一端写一端读并记入 filedes[]中。其中 filedes[0]是读取管道的文件标识号filedes[1]是写入管道的文件标识号。 说明 父子进程使用无名管道通信是建立在子进程继承父进程资源的基础上。父子进程通信时必须先建立管道再创建子进程。 使用管道时必须确定管道通信的方向且一旦确定后不能改变。 父子进程中一个进程只能使用一个文件标识号所以另一个不使用的标识号可以使用系统调用close关闭它。 举例在该例中父进程建立管道后创建一个子进程。子进程的任务是把一组字符串信息写入管道父进程在子进程完成任务终止后从管道中读取信息并显示在显示器上。
#include stdio.h
Main()
{
Pid_t pid;
Int fds[2];
Char buf1[50],buf2[50];
Pipe(fds); /*建立无名管道*/
Ifpidfork0/*创建子进程失败程序终止*/
{
Printf“Fork Error\n”
Exit1
}
Else if(pid0) /*子进程*/
{
Close(fds[0]); /*关闭不使用的文件标识号*/
Sprintf(buf1,”these are transmitted data\n”); /*把信息写入缓冲区 buf1*/
Write(fds[1],buf1,50); /*把缓冲区 buf1 中的信息写入管道*/
Exit1 /*子进程终止*/
}
Else
{
Close(fds[1]); /*关闭不使用的文件标识号*/
Wait0 /*等待子进程结束*/
Read(fds[0],buf2,50); /*读管道信息并把信息置入 buf2*/
Printf“%s\n”buf2/*显示 buf2 中的信息*/
}
}说明 1、无名管道与一般文件不同它没有纳入文件系统的目录不占用外存空间仅使用内存作为数据传输的缓冲区。 2、缓冲区的大小决定每次写入管道的字节数。该值由全局符号常量 PIPE BUF 确定。 缺省值为一个物理页面。 3、由文件系统管理但此时没有文件系统知识基础故暂时不讲详细管理 4.6.2 命名管道
又称 FIFO 管道。命名管道与无名管道的区别命名管道有文件名在文件系统中可见可以实现任意进程间的通信。
1.终端使用
使用 mkfifo 建立一个命名管道。 例$mkfifo myfifo/*建立一个名字为 myfifo 的管道。 此时使用 ls 命令就可以查看到该文件信息。
$ls –l myfifo
prw-r---- wang user 0 fen 22 1345 myinfo /*第一个字符 p表示是 FIFO 文件
在命名管道建立后就可以用它在两个进程间进行通信。如
$cut –c1-5 myfifo
$cat file1 myfifo
其中 cat 命令把文件 file1 的内容写入管道 myfifo命令 cut 从管道 myfifo 中读出文件的内容进行裁剪后显示每行的前 1~5 个字符。2.程序中使用
1建立命名管道 方法一调用 C 函数 mkfifo实现的其定义如
#include sys/state.h
Int mkfifo(const char *path, mode_t mode);其中 path指明要创建的命名管道的路径和名字 mode指明管道访问的权限。 创建成功返回 0否则为负数。 另一种方法使用 linux 系统调用 mknod mknod可以建立任何类型的文件在建立命名管道时使用的形式如下 mknodpathmode|S_FIFO,0; 参数含义与上同其中 S_FIFO 表示建立 FIFO 文件。 这两种方法作用基本相同建立命名管道的目录结构、inode 节点、file 文件结构体等。 2打开管道
由于任何进程都可以通过命名管道进行通信所以在使用命名管道时必须先打开它由系统调用open实现。
openchar *path, int mode其中 path指明要使用的命名管道的路径和名字 mode指明管道访问的模式O_RDONLY(只读)、O_WRONLY只写 创建成功返回文件标识号否则为负数。 注在使用文件操作对管道进行各种操作时要使用文件标识号而不是管道名。 例有两个程序其中 wrfifo.c 把一组信息写入管道另一个程序 rdfifo.c 把管道中的信息读出后显示在 屏幕上。
/*读管道程序 rdfifo.c*/
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include stdio.h
#include stdlib.h
#include limits.h
Main(void)
{
Int fd,len;
Char buf[PIPE_BUF];
Mode_t mode0666;
If(mkfifo(“fifo1”,mode)0)
{
Printf(“mkfifo error\n”);
Exit(1);
}
If((fdopen“fifo1”,O_RDONLY))0
{
Printf(“pipe open error\n”);
Exit(1);
}
While(len(read(fd,buf,PIPE_BUF-1)0)
Printf(“read fifo pipe: %s”,buf);
Close(fd);
}
/*写管道程序 wdfifo.c*/
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include stdio.h
#include stdlib.h
#include limits.h
Main(void)
{
Int fd,len;
Char buf[PIPE_BUF];
Mode_t mode0666;
If((fdopen“fifo1”,O_WRONLY))0
{
Printf(“pipe open error\n”);
Exit(1);
}
Fori0i3;i
{
Lensprintf(buf,”write fifo pipe from %d at %d times\n”,getpid(),i1);
Write(fd,buf,len1);
}
Close(fd);
}
在 linux 终端上运行这两个程序
$./rdfifo
$./wrfifo
结果
Write fifo pipe from 945 at 1 times
Write fifo pipe from 945 at 2 times
Write fifo pipe from 945 at 3 times