14.有名管道通信
14.有名管道通信
有名管道:
有名管道又称为FIFO文件,因此我们对有名管道的操作可以采用操作文件的方法,如使用
open,read,write等.
有名管道的学习:
有名管道与其他文件的对比:
FIFO文件在使用上和普通文件有相似之处,但是也有不同之处:
1. 读取Fifo文件的进程只能以"RDONLY"方式打开fifo文件。
2. 写Fifo文件的进程只能以"WRONLY"方式打开fifo文件。
3. Fifo文件里面的内容被读取后,就消失了。但是普通文件里面的内容读取后还存在。
创建有名管道:man 3 mkfifo:
NAME
mkfifo - make a FIFO special file (a named pipe)
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
DESCRIPTION
mkfifo() makes a FIFO special file with name pathname. mode specifies the
FIFO's permissions. It is modified by the process's umask in the usual way:
the permissions of the created file are (mode & ~umask).
A FIFO special file is similar to a pipe, except that it is created in a dif-
ferent way. Instead of being an anonymous communications channel, a FIFO spe-
cial file is entered into the file system by calling mkfifo().
Once you have created a FIFO special file in this way, any process can open it
for reading or writing, in the same way as an ordinary file. However, it has
to be open at both ends simultaneously before you can proceed to do any input
or output operations on it. Opening a FIFO for reading normally blocks until
some other process opens the same FIFO for writing, and vice versa. See
fifo(7) for non-blocking handling of FIFO special files.
RETURN VALUE
On success mkfifo() returns 0. In the case of an error, -1 is returned (in
which case, errno is set appropriately).
ERRORS
EACCES One of the directories in pathname did not allow search (execute) per-
mission.
EEXIST pathname already exists. This includes the case where pathname is a
symbolic link, dangling or not.
ENAMETOOLONG
Either the total length of pathname is greater than PATH_MAX, or an
individual filename component has a length greater than NAME_MAX. In
the GNU system, there is no imposed limit on overall filename length,
but some file systems may place limits on the length of a component.
ENOENT A directory component in pathname does not exist or is a dangling sym-
bolic link.
ENOSPC The directory or file system has no room for the new file.
ENOTDIR
A component used as a directory in pathname is not, in fact, a direc-
tory.
EROFS pathname refers to a read-only file system.
CONFORMING TO
POSIX.1-2001.
SEE ALSO
mkfifo(1), close(2), open(2), read(2), stat(2), umask(2), write(2), mkfi-
foat(3), fifo(7)
COLOPHON
This page is part of release 3.22 of the Linux man-pages project. A descrip-
tion of the project, and information about reporting bugs, can be found at
http://www.kernel.org/doc/man-pages/.
创建有名管道的函数名:mkfifo:
原型:int mkfifo(const char *pathname, mode_t mode);
该函数的功能是创建一个有名管道,即是一个fifo文件。
需要的头文件:
#include <sys/types.h>
#include <sys/stat.h>
返回值:成功返回0,失败是返回-1.
参数说明:
pathname:要创建的fifo文件的名字,带路径的。
mode:创建的fifo文件的访问权限
删除有名管道:
查看信息:man 2 unlink:
NAME
unlink - delete a name and possibly the file it refers to
SYNOPSIS
#include <unistd.h>
int unlink(const char *pathname);
DESCRIPTION
unlink() deletes a name from the file system. If that name was the last link
to a file and no processes have the file open the file is deleted and the space
it was using is made available for reuse.
If the name was the last link to a file but any processes still have the file
open the file will remain in existence until the last file descriptor referring
to it is closed.
If the name referred to a symbolic link the link is removed.
If the name referred to a socket, fifo or device the name for it is removed but
processes which have the object open may continue to use it.
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set
appropriately.
ERRORS
EACCES Write access to the directory containing pathname is not allowed for the
process's effective UID, or one of the directories in pathname did not
allow search permission. (See also path_resolution(7).)
EBUSY (not on Linux)
The file pathname cannot be unlinked because it is being used by the
system or another process and the implementation considers this an
error.
EFAULT pathname points outside your accessible address space.
EIO An I/O error occurred.
EISDIR pathname refers to a directory. (This is the non-POSIX value returned
by Linux since 2.1.132.)
ELOOP Too many symbolic links were encountered in translating pathname.
ENAMETOOLONG
pathname was too long.
ENOENT A component in pathname does not exist or is a dangling symbolic link,
or pathname is empty.
ENOMEM Insufficient kernel memory was available.
ENOTDIR
A component used as a directory in pathname is not, in fact, a direc-
tory.
EPERM The system does not allow unlinking of directories, or unlinking of
directories requires privileges that the calling process doesn't have.
(This is the POSIX prescribed error return; as noted above, Linux
returns EISDIR for this case.)
EPERM (Linux only)
The file system does not allow unlinking of files.
EPERM or EACCES
The directory containing pathname has the sticky bit (S_ISVTX) set and
the process's effective UID is neither the UID of the file to be deleted
nor that of the directory containing it, and the process is not privi-
leged (Linux: does not have the CAP_FOWNER capability).
EROFS pathname refers to a file on a read-only file system.
CONFORMING TO
SVr4, 4.3BSD, POSIX.1-2001.
BUGS
Infelicities in the protocol underlying NFS can cause the unexpected disappear-
ance of files which are still being used.
SEE ALSO
rm(1), chmod(2), link(2), mknod(2), open(2), rename(2), rmdir(2), unlinkat(2),
mkfifo(3), remove(3), path_resolution(7), symlink(7)
COLOPHON
This page is part of release 3.22 of the Linux man-pages project. A descrip-
tion of the project, and information about reporting bugs, can be found at
http://www.kernel.org/doc/man-pages/.
该函数的原型:
int unlink(const char *pathname);
需要的头文件:unistd.h.
该函数的功能是删除文件。
执行成功则返回0,失败是返回-1.
参数说明:
pathname:用来指定要删除的文件名字(含路径)。
到这里我们就知道了管道的一系列的操作。现在写两个独立进程利用有名管道来通信。写进程的功能是创建FIFO管道,同时写入数据。读进程则是读取fifo里的数据,显示读出的数据。看看写入和读出是否一致。
首先实现写有名管道的程序:write.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
void main(){
int fd;
//reate fifo file
mkfifo("/home/jin",0666);
//open fifo file
fd = open("/home/jin",O_WRONLY);
//write data into fifo file
write(fd,"forfish",8);
close(fd);
}
上面是往一个命名管道写数据。
有名管道的read.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
void main(){
char my_buf[15];
int fd;
fd = open("/home/jin",O_RDONLY);
read(fd,my_buf,8);
printf("read %s \n",my_buf);
close(fd);
unlink("/home/jin");
}
这是有名管道的读出数据。
执行的过程:
先执行write.c:如下,有名管道的写数据进入等待进程把数据读出,进入阻塞状态。这也是命名管道的一个特点。
上面的过程,当我们运行了读进程。从命名管道读出数据后,write进程的阻塞状态也结束了。