LInux系统编程学习之《管道的应用》

今天来总结一些管道的应用

有时候我们需要在父进程和子进程之间进行信息的交换通信,那么管道就是我们选择的一种办法


1.匿名管道

创建匿名管道需要使用pipe函数

/*
 * #include <unistd.h>
 * int pipe(int pipedes[2]);
 * 成功返回0,出错返回-1,错误记录在errno变量中
 * pipedes是用来定义管道的读取文件
 * pipedes[0]用于从管道中读,pipedes[1]用于从管道中写
 */

例子:我们现在写一个程序,子进程对管道近进行写数据,父进程对管道进行读数据

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>

int main(int argc,char ** argv)
{
    int fd[2],nbytes;
    pid_t childpid;
    char string[] = "Hello world!\n";
    char readbuffer[80];

    pipe(fd);  //创建管道,传入一个数量为2的一维数组即可

    if ((childpid = fork())==-1)  //创建子进程
    {
        perror("fork");
        _exit(1);
    }
	if (0 == childpid)
	{
        close(fd[0]);   //子进程关闭读取管道,即fd[0]
        write(fd[1],string,strlen(string));  //子进程写入数据到管道中
        _exit(0);
	}
    else
    {
        close(fd[1]);  //父进程关闭写入管道,即fd[1]
        nbytes = read(fd[0],readbuffer,sizeof(readbuffer)); //父进程从管道中读取数据
        printf("Receive string:%s",readbuffer);  //把读到的数据打印出来
    }
    return 0;
}
使用匿名管道需要注意的地方:

1.pipe()的调用必须在fork()之前

2.及时关闭不需要的管道句柄

3.使用dup()之前确定定向的目标是最小的文件句柄

4.匿名管道只能实现在父子进程间的通信,如果两个进程之间没有fork()关系,就必须考虑其他的进程通信方法


2.有名管道

为了解决管道不能提供非父子关系进程的通信缺陷,在管道的基础上发展了有名管道

有名管道不仅具有了管道的通信功能,还具有了普通文件的优点(可以被多个进程共享,可长期存在),有效的解决了管道通信的缺点、

建立有名管道的函数如下:

/*
 * #include <sys/stat.h>
 * int mknod(char * pathname,mode_t mode,dev_t dev);
 * 成功返回0,出错返回-1
 * pathname:管道的路径
 * mode:文件的权限
 * dev:设备号,一般填0
 */

下面是一个有名管道的例子,例子中,建立一个有名管道,向管道内读写信息:

创建管道,并等到管道内信息到来:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/stat.h>

#define FIFO_FILE "sample_fifo_test"

int main()
{
	FILE * fp;
	char readbuf[80];
	umask(0);  //清除mask标记
	mknod(FIFO_FILE,S_IFIFO | 0666,0);  //创建有名管道
	while (1)
	{
		fp = fopen(FIFO_FILE,"r");     //打开管道
		fgets(readbuf,80,fp);      //读取管道中信息
		printf("Receiver string:%s\n",readbuf);  //打印信息
		fclose(fp);  //使用完关闭管道
	}
	return 0;
}

打开管道,向管道内写入信息:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/stat.h>

#define FIFO_FILE "sample_fifo_test"

int main()
{
	FILE * fp;
	char buf[255];

	while (NULL != gets(buf))    //获取项管道内写入的信息
	{
		fp = fopen(FIFO_FILE,"w");  //打开管道
		fputs(buf,fp);  //写入信息到管道内
		fclose(fp);  //关闭管道
	}
	return 0;
}

有名管道使用注意:

1.有名管道一次写入的数据量有限制,在头文件<linux/limits.h>中的PIPE_BUF可以获取,如果一次写入的数据超过这个值,则会分多次写入,这时如果有多个程序在使用管道,则可能会出现数据不一致的情况

2.有名管道必须同时有读/写两个进程。如果一个进程试图向一个没有读入端进程的有名管道写入数据,一个SIGPIPE信号会产生。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值