您的位置:首页 > 运维架构 > Linux

linux的管道和命名管道

2012-10-25 16:24 120 查看
1.管道pipe

int pipe( int fd[2] );

返回值:成功,返回0,否则返回-1。参数数组包含pipe使用的两个文件的描述符。fd[0]:读管道,fd[1]:写管道。

必须在fork()中调用pipe(),否则子进程不会继承文件描述符。两个进程不共享祖先进程,就不能使用pipe。但是可以使用命名管道。

[cpp]
view plaincopy

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
int pipe_fd[2];
pid_t pid;
char buf_r[100];
char* p_wbuf;
int r_num;
memset(buf_r,0,sizeof(buf_r));
if(pipe(pipe_fd)<0)
{
printf("pipe create error\n");
return -1;
}
if((pid=fork())==0)
{
printf("\n");
close(pipe_fd[1]); /*关闭写管道描述符*/
sleep(2);
if((r_num=read(pipe_fd[0],buf_r,100))>0){
printf("%d numbers read from the pipe is %s\n",r_num,buf_r);
}
close(pipe_fd[0];
exit(0);
}
else if(pid>0){
close(pipe_fd[0]);
if(write(pipe_fd[1],"hello",5)!=-1)
printf("parent write1 success!\n");
if(write(pipe_fd[1],"pipe",5)!=-1)
printf("parent write2 success!\n");
close(pipe_df[1]);
sleep(3);
waitpid(pid,NULL,0);
exit(0);
}
}

2.流管道

[cpp]
view plaincopy

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

#define BUFSIZE 1000

int main()
{
FILE *fp;
char *cmd = "ps -ef";
char buf[BUFSIZE];
buf[BUFSIZE] = '\0';
if((fp=popen(cmd,"r"))==NULL)
perror("popen");
while((fgets(buf,BUFSIZE,fp))!=NULL)
printf("%s",buf);
pclose(fp);
exit(0);
}

3.命名管道FIFO

特点:1.FIFO是作为一个特殊的设备文件存在;

2.不同祖先进程的进程之间可以共享数据;

3.使用完后FIFO将继续保存。

[cpp]
view plaincopy

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo" //管道位置

main(int argc,char** argv)
{
char buf_r[100];
int fd;
int nread;

if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST)) //创建并执行
printf("cannot create fifoserver\n");
printf("Preparing for reading bytes...\n");

memset(buf_r,0,sizeof(buf_r));
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0); //readonly 不阻塞
if(fd==-1)
{
perror("open");
exit(1);
}
while(1)
{
memset(buf_r,0,sizeof(buf_r));

if((nread=read(fd,buf_r,100))==-1){ //读取管道
if(errno==EAGAIN)
printf("no data yet\n");
}
printf("read %s from FIFO\n",buf_r);
sleep(1);
}
pause();
unlink(FIFO);
}

通常对命名管道的读在写之前。

[cpp]
view plaincopy

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/tmp/myfifo"

main(int argc,char** argv) //argc:参数个数? argv:参数
{
int fd;
char w_buf[100];
int nwrite;

if(fd==-1)
if(errno==ENXIO)
printf("open error; no reading process\n");
fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0); //writeonly,管道已在read中创建,可以直接打开。
if(argc==1)
printf("Please send something\n");
strcpy(w_buf,argv[1]);
if((nwrite=write(fd,w_buf,100))==-1) //write
{
if(errno==EAGAIN)
printf("The FIFO has not been read yet.Please try later\n");
}
else
printf("write %s to the FIFO\n",w_buf);
}

FIFO创建后,可以用open(),close(),read(),write(),unlink()等流操作函数操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: