[Linux]进程之间的管道通信

来源:互联网 发布:绿地控股历史价格数据 编辑:程序博客网 时间:2024/05/28 11:50

一、什么是管道

UNIX系统在OS的发展上,最重要的贡献之一便是该系统首创了管道(pipe)。这也是UNIX系统的一大特色。所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。由写进程从管道的写入端(句柄fd1)将数据写入管道,而读进程则从管道的读出端(句柄fd2)读出数据。

这里写图片描述

二、管道的类型:

1.有名管道
一个可以在文件系统中长期存在的、具有路径名的文件。用系统调用mknod( )建立。它克服无名管道使用上的局限性,可让更多的进程也能利用管道进行通信。因而其它进程可以知道它的存在,并能利用路径名来访问该文件。对有名管道的访问方式与访问其他文件一样,需先用open( )打开。
2.无名管道
一个临时文件。利用pipe( )建立起来的无名文件(无路径名)。只用该系统调用所返回的文件描述符来标识该文件,故只有调用pipe( )的进程及其子孙进程才能识别此文件描述符,才能利用该文件(管道)进行通信。当这些进程不再使用此管道时,核心收回其索引结点。二种管道的读写方式是相同的,本文只讲无名管道。
3.pipe文件的建立
分配磁盘和内存索引结点、为读进程分配文件表项、为写进程分配文件表项、分配用户文件描述符
4.读/写进程互斥
内核为地址设置一个读指针和一个写指针,按先进先出顺序读、写。为使读、写进程互斥地访问pipe文件,需使各进程互斥地访问pipe文件索引结点中的直接地址项。因此,每次进程在访问pipe文件前,都需检查该索引文件是否已被上锁。若是,进程便睡眠等待,否则,将其上锁,进行读/写。操作结束后解锁,并唤醒因该索引结点上锁而睡眠的进程。

三、所涉及的系统调用

1.pipe( )
建立一无名管道。
系统调用格式
pipe(fd)
参数定义
int pipe(fd);
int fd[2];
其中,fd[1]是写入端,fd[0]是读出端。
功能:pipe()会建立管道,并将文件描述词由参数fd数组返回。
该函数使用头文件如下:

#include <unistd.h>#inlcude <signal.h>#include <stdio.h>

2.read( )
系统调用格式
read(fd,buf,nbyte)
功能:从fd所指示的文件中读出nbyte个字节的数据,并将它们送至由指针buf所指示的缓冲区中。如该文件被加锁,等待,直到锁打开为止。
参数定义

        int  read(fd,buf,nbyte);              int  fd;              char *buf;              unsigned  nbyte;

3.write( )
系统调用格式
write(fd,buf,nbyte)
功能:把nbyte 个字节的数据,从buf所指向的缓冲区写到由fd所指向的文件中。如文件加锁,暂停写入,直至开锁。
参数定义同read( )。
4.sprintf( )
格式化字符串复制。
系统调用格式:
int sprintf(char *str,const char *format)
函数说明:
sprintf()会根据参数format字符串来转换并格式化数据,然后将结果复制到参数str 所指的字符串数组,直到出现字符串结束(‘\0’)为止。
返回值:成功则返回参数str字符串长度,失败则返回-1。
附加说明:使用此函数得留意堆栈溢出(buffer overflow)。
5. sleep()
让进程暂停执行一段时间。
系统调用格式:
unsigned int sleep(unsigned int seconds)
函数说明:
Sleep()会令目前进程暂停(进入睡眠状态),直到达到参数seconds 所指定的时间,或被信号中断。
返回值:若进程暂停到参数seconds所指定的时间则返回0,若有信号中断则返回剩余秒数。
6.lockf()
锁定文件的某些段或整个文件。
系统调用格式:

int lockf(files,function,size)int files,function;long size;

函数说明:files是文件描述符(1:标准输出设备屏幕,0:标准输入设备键盘),function是锁定和解锁(1:锁定,0:解锁),size是锁定或解锁的字节数,若用0,表示从文件的当前位置到文件尾。

看例子

#include<stdlib.h>#include<unistd.h>#include<signal.h>#include<stdio.h>int pid1,pid2;main(){    int fd[2];    char OutPipe[100],InPipe[100];    pipe(fd);    while((pid1=fork())== -1);    if(pid1==0)    {         lockf(fd[1],1,0);        sprintf(OutPipe,"child 1 process is sending message!");        write(fd[1],OutPipe,50);        sleep(1);        lockf(fd[1],0,0);        exit(0);    }    else    {        while((pid2=fork())== -1);        if(pid2==0)        {            lockf(fd[1],1,0);            sprintf(OutPipe,"child 2 process is sending message!");            write(fd[1],OutPipe,50);            sleep(1);            lockf(fd[1],0,0);            exit(0);        }        else        {            wait(0);            read(fd[0],InPipe,50);            printf("%s\n",InPipe);            wait(0);            read(fd[0],InPipe,50);            printf("%s\n",InPipe);            exit(0);        }    }}

这里写图片描述

两个子进程分别往无名管道中写入一条消息,父进程分别读出消息。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果七plus流量打不开怎么办 苹果手机突然打不开流量怎么办 天猫商家迟迟不发货怎么办 苹果7开不开机了怎么办 苹果机黑屏了开不起来怎么办 美团收银机连不上网怎么办 6s换电池后黑屏怎么办 苹果上的软件打不开也删不掉怎么办 苹果手机打开软件打不开怎么办 苹果电脑下载的软件打不开怎么办 苹果手机下载的软件都打不开怎么办 苹7果屏幕黑屏怎么办 苹果6s手机打不开怎么办 苹果ipad密码输入打不开怎么办 苹果平板黑屏了打不开怎么办 苹果6sp电影商城打不开怎么办 苹果6应用商城打不开怎么办 游戏下载好了安装不上怎么办 苹果5s应用商店不见了怎么办 id被停用手机白板打不开怎么办 苹果6s下载不了软件怎么办 苹果下载的软件打不开怎么办 苹果6s下不了app怎么办 苹果手机因为闪退打不开了怎么办 天猫方糖坏了怎么办 天猫魔盒的遥控器坏了怎么办 天猫盒子没声音怎么办 天猫魔盒播放声音很低怎么办 天猫魔盒3a卡顿怎么办 天猫网络机顶盒打不开了怎么办 天猫机顶盒遥控器丢了怎么办 天猫机顶盒没有遥控器怎么办 天猫机顶盒很卡怎么办 天猫机顶盒没遥控器怎么办 天猫机顶盒看不了怎么办 天猫机顶盒变黑白怎么办 天猫精灵丢了怎么办 咪咕盒子没信号怎么办 猫los灯亮了怎么办 网络猫los闪红灯怎么办 台式电脑二级网页打不开.怎么办