linux进程通信之(四):有名管道的读与写
时间:2010-11-03 来源:andyluo324324
前面我们说了无名管道,下面我们来说说有名管道,请看下面一段代码:
fifo_write.c:
#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" void main(int argc,char **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);//打开FIFO管道,并设置非阻塞状态
fd=open(FIFO,O_WRONLY|O_NONBLOCK,0);
if(argc==1)
{
printf("please send something \n");
}
strcpy(w_buf,argv[1]);
if((nwrite=write(fd,w_buf,100))==-1)//向管道中写入字符串
{
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) ;
}
} /*------------------------------------------------------------
1.有名管道说明
它可以使互不相关的两个进程实现彼此通信.该管道可以通过路径名来指出,并且在文件系
统中是可见的.在建立管道之后,两个进程就可以把它当作普通文件一样进行读写操作,使用
方便.不过值得注意的是,FIFO是严格地遵循先进先出规则的,对管道及FIFO的读总是从开始处
返回数据,对它们的写则把数据添加到末尾,它们不支持如lseek()等文件定位操作.
2.有名管道的创建可以使用函数mkfifo(),该函数类似文件中的open()操作,可以指定管道的
路径和打开的模式.
在创建管道成功之后,就可以使用open,read,write这些函数了.与普通文件的开发设置一样,
对于为读而开的管道可在open中设置O_RDONLY,对于为写而打开的管道可在open中设置O_WRONLY,
在这里与普通文件不同的是阻塞的可能.由于普通文件的读写时不会出现阻塞问题,而
在管道的读写中却有阻塞的可能,这里的非阻塞标志可以在open函数中设定为O_NONBLOCK.
对于读进程
.若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞直到有数据写入.
.若该管道是非阻塞打开,则无论FIFO内是否有数据,读进程都会立即执行读操作.
对于写进程
.若该管道是阻塞打开,则写进程而言将一直阻塞直到有读进程读出数据.
.若该管道是非阻塞打开,则当前FIFO内没有读操作,写进程都会立即执行读操作.
3.mkfifo函数格式
1)所需要的头文件
#include<sys/types.h>
#include<sys/state.h>
2)函数原型
int mkfifo(const char *filename,mode_t mode)
3)函数输入参数
filename:要创建的管道
mode:
O_RDONLY:读管道
O_WRONLY:写管道
O_RDWR:读写管道
O_NONBLOCK:非阻塞
O_CREAT:如果该文件不存在,那么就创建一个新的文件,并用第三的参数为其设置权限.
O_EXCL:如果使用O_CREAT时文件存在,那么可返回错误消息.这一参数可测试文件是否
存在.
4)函数返回值
成功:0
出错:-1
4.实验
本实例需要两个程序,一个用于读管道,另一个用于写管道.其中在写管道的程序里创建
管道,并且作为main函数里的参数由用户输入要写入的内容.读管道读出了用户写入管道
的内容.
1)[root@localhost the_eight_step]# gcc fifo_write.c -o fifo_write
2)[root@localhost the_eight_step]# ./fifo_write hello
write hello to the fifo
3)[root@localhost the_eight_step]# gcc fifo_read.c -o fifo_read
4)[root@localhost the_eight_step]# ./fifo_read
perparing for reading bytes ...
read from fifo
read from fifo
read from fifo
read from fifo
read hello from fifo
5)注意:要打开两个终端去观察两个程序的运行情况.
----------------------------------------------------------*/ fifo_read.c: #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"
void 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("perparing for reading bytes ... \n");
memset(buf_r,0,sizeof(buf_r));
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);//打开有名管道,并设置为非阻塞方式
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);
} /*--------------------------------------------
notes:
1.unlink(删除文件)
1)所需要的头文件:#include<unistd.h>
2)函数原型:int unlink(const char *pthname)
3)函数说明:unlink()会删除参数pthbame指定的文件,如果该文件名为最后连接点,但有其他进程
打开此文件,则在所有关于此文件的文件描述词皆关闭后才会删除.如果参数pathname为一符号连
接,则此连接会被删除.
4)返回值
成功则返回0
失败返回-1
错误原因存于errno
2.pause(让进程暂停直到信号出现)
1)所需要的头文件:#include<unistd.h>
2)函数原型:int pause(void)
3)函数说明:pause()会令目前的进程暂停(进入睡眠状态),直到被信号(signal)所中断.
4)返回值
只返回-1
错误代码EINTR有信号到达中断了此函数
------------------------------------------------*/
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define FIFO "/tmp/myfifo" void main(int argc,char **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);//打开FIFO管道,并设置非阻塞状态
fd=open(FIFO,O_WRONLY|O_NONBLOCK,0);
if(argc==1)
{
printf("please send something \n");
}
strcpy(w_buf,argv[1]);
if((nwrite=write(fd,w_buf,100))==-1)//向管道中写入字符串
{
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) ;
}
} /*------------------------------------------------------------
1.有名管道说明
它可以使互不相关的两个进程实现彼此通信.该管道可以通过路径名来指出,并且在文件系
统中是可见的.在建立管道之后,两个进程就可以把它当作普通文件一样进行读写操作,使用
方便.不过值得注意的是,FIFO是严格地遵循先进先出规则的,对管道及FIFO的读总是从开始处
返回数据,对它们的写则把数据添加到末尾,它们不支持如lseek()等文件定位操作.
2.有名管道的创建可以使用函数mkfifo(),该函数类似文件中的open()操作,可以指定管道的
路径和打开的模式.
在创建管道成功之后,就可以使用open,read,write这些函数了.与普通文件的开发设置一样,
对于为读而开的管道可在open中设置O_RDONLY,对于为写而打开的管道可在open中设置O_WRONLY,
在这里与普通文件不同的是阻塞的可能.由于普通文件的读写时不会出现阻塞问题,而
在管道的读写中却有阻塞的可能,这里的非阻塞标志可以在open函数中设定为O_NONBLOCK.
对于读进程
.若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞直到有数据写入.
.若该管道是非阻塞打开,则无论FIFO内是否有数据,读进程都会立即执行读操作.
对于写进程
.若该管道是阻塞打开,则写进程而言将一直阻塞直到有读进程读出数据.
.若该管道是非阻塞打开,则当前FIFO内没有读操作,写进程都会立即执行读操作.
3.mkfifo函数格式
1)所需要的头文件
#include<sys/types.h>
#include<sys/state.h>
2)函数原型
int mkfifo(const char *filename,mode_t mode)
3)函数输入参数
filename:要创建的管道
mode:
O_RDONLY:读管道
O_WRONLY:写管道
O_RDWR:读写管道
O_NONBLOCK:非阻塞
O_CREAT:如果该文件不存在,那么就创建一个新的文件,并用第三的参数为其设置权限.
O_EXCL:如果使用O_CREAT时文件存在,那么可返回错误消息.这一参数可测试文件是否
存在.
4)函数返回值
成功:0
出错:-1
4.实验
本实例需要两个程序,一个用于读管道,另一个用于写管道.其中在写管道的程序里创建
管道,并且作为main函数里的参数由用户输入要写入的内容.读管道读出了用户写入管道
的内容.
1)[root@localhost the_eight_step]# gcc fifo_write.c -o fifo_write
2)[root@localhost the_eight_step]# ./fifo_write hello
write hello to the fifo
3)[root@localhost the_eight_step]# gcc fifo_read.c -o fifo_read
4)[root@localhost the_eight_step]# ./fifo_read
perparing for reading bytes ...
read from fifo
read from fifo
read from fifo
read from fifo
read hello from fifo
5)注意:要打开两个终端去观察两个程序的运行情况.
----------------------------------------------------------*/ fifo_read.c: #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"
void 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("perparing for reading bytes ... \n");
memset(buf_r,0,sizeof(buf_r));
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);//打开有名管道,并设置为非阻塞方式
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);
} /*--------------------------------------------
notes:
1.unlink(删除文件)
1)所需要的头文件:#include<unistd.h>
2)函数原型:int unlink(const char *pthname)
3)函数说明:unlink()会删除参数pthbame指定的文件,如果该文件名为最后连接点,但有其他进程
打开此文件,则在所有关于此文件的文件描述词皆关闭后才会删除.如果参数pathname为一符号连
接,则此连接会被删除.
4)返回值
成功则返回0
失败返回-1
错误原因存于errno
2.pause(让进程暂停直到信号出现)
1)所需要的头文件:#include<unistd.h>
2)函数原型:int pause(void)
3)函数说明:pause()会令目前的进程暂停(进入睡眠状态),直到被信号(signal)所中断.
4)返回值
只返回-1
错误代码EINTR有信号到达中断了此函数
------------------------------------------------*/
相关阅读 更多 +