1. 命名管道基础
命名管道也被称为FIFO文件, 在文件系统中是可见的,并且跟其它文件一样可以读写!
命名管道特点:
- 当写进程向管道中写数据的时候,如果没有进程读取这些数据,写进程会堵塞
- 当读取管道中的数据的时候,如果没有数据,读取进程会被堵塞
- 当写进程堵塞的时候,有读进程读取数据,那么写进程恢复正常
-
当读进程堵塞的时候,如果写进程写了数据,那么读进程会读取数据,然后正常执行后面的代码
2. shell
2.1 创建管道:
$ mkfifo /tmp/testpipe
2.2 命令行间通讯
cat < /tmp/testpipe &
echo "hegaozhi" > /tmp/testpipe
2.3 read
#########################################################################
# File Name: reader.sh
# Author: hegaozhi
# mail: [email protected]
# Created Time: 2020年01月03日 星期五 11时05分19秒
#########################################################################
#!/bin/bash
# filename: reader.sh
# 逐行读取管道中的内容
pipe=/tmp/testpipe
trap "rm -f $pipe" EXIT
if [[ ! -p $pipe ]]; then
mkfifo $pipe
fi
while true
do
if read line <$pipe; then
if [[ "$line" == 'quit' ]]; then
break
else
echo $line
fi
fi
done
echo "Stop reader...."
2.4 write
#########################################################################
# File Name: writer.sh
# Author: hegaozhi
# mail: [email protected]
# Created Time: 2020年01月03日 星期五 11时07分18秒
#########################################################################
#!/bin/bash
# writer.sh
# 把当前进程的pid写到管道
pipe=/tmp/testpipe
if [[ ! -p $pipe ]]; then
echo "Reader not running"
exit 1
fi
while true
do
if [[ "$1" ]]; then
echo "$1" >$pipe
else
echo "Hello from $$" >$pipe
fi
sleep 1
done
3. C语言
3.1 reader.c
/*************************************************************************
> File Name: reader.c
> Author: hegaozhi
> Mail: [email protected]
> Created Time: 2020年01月03日 星期五 11时25分07秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#define FIFO "/tmp/testpipe"
int main()
{
int rfd;
char str[32];
int i ;
printf("读程序\n");
if(access(FIFO,F_OK))
{
int ret = mkfifo(FIFO,0777);
if(ret == -1)
{
printf("Create FIFO failed!\n");
return -1;
}
}
rfd = open( FIFO , O_RDWR); //O_RDONLY 只读且阻塞
if(rfd==-1)
{
printf("Open file error\n");
exit(1);
}
while(1)
{
memset(str,0,sizeof(str));
if((i=read(rfd,str,sizeof(str)))>0)
printf("read:%s\n",str);
}
close(rfd);
}
3.2 write
/*************************************************************************
> File Name: writer.c
> Author: hegaozhi
> Mail: [email protected]
> Created Time: 2020年01月03日 星期五 11时25分49秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#define FIFO "/tmp/testpipe"
int main(int argc,char *argv[])
{
if(argc < 2)
return 0;
int wfd;
char str[32];
char *str1 = "\n";
if(access(FIFO,F_OK))
{
int ret =mkfifo(FIFO,0777);
if(ret == -1)
{
printf("Create FIFO failed!\n");
return -1;
}
}
sscanf(argv[1], "%s",str);
strcat(str,str1);
wfd =open(FIFO, O_WRONLY|O_TRUNC); //可读可写,存在数据则清空; O_WRONLY 只写且阻塞
if(wfd<=0)
return 0;
write(wfd, str, sizeof(str));
close(wfd);
exit(0);
}