管道的不足之处是没有名字,只能用于具有亲缘关系的进程间通信。有名管道(Named Pipe或FIFO)可以在互不相关的两个进程间实现彼此通信。有名管道提供了一个路径名与之关联。有名管道是一个设备文件。有名管道严格按照先进先出的规则。对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数据添加到末尾,不支持lseek等文件定位操作。有名管道的创建在Shell方式下可以使用mkfifo()函数和mknod()函数。创建成功后就可以使用open()、read()和write()函数了。
mkfifo()函数原型为
mkfifo()函数会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限(mode%~umask),因此,umask值也会影响到FIFO文件的权限。由mkfifo()建立的FIFO文件,其他进程都可以用读写一般文件的方式存取。当使用open()打开FIFO文件时,O_NONBLOCK会有如下影响。
当使用O_NONBLOCK旗标时,打开FIFO文件来读取的操作会立刻返回,但是若还没有其他进程打开FIFO文件来读取,则写入的操作会返回ENXIO错误代码。
没有使用O_NONBLOCK旗标时,打开FIFO文件来读取的操作会等到其他进程打开FIFO文件来写入后才正常返回。同样,打开FIFO文件来写入的操作会等到其他进程打开FIFO文件来读取后才正常返回。
若成功,则返回0,否则返回-1。错误原因存于errno中。
错误代码:
●EACCESS参数pathname所指定的目录路径无可执行的权限。
●EEXIST参数pathname所指定的文件已存在。
●ENAMETOOLONG参数pathname的路径名称太长。
●ENOENT参数pathname包含的目录不存在。
●ENOSPC文件系统的剩余空间不足。
●ENOTDIR参数pathname路径中的目录存在,但却不是真正的目录。
●EROFS参数pathname指定的文件存在于只读文件系统内。
mkfifo()使用示例如下:
S_IFIFO|0666指明创建一个有名管道并且读取权限为0666,即创建者、与创建者同组的用户、其他用户对该有名管道的访问权限都是可读可写的。(www.xing528.com)
mknod()函数原型为
该函数中的参数pathname为创建的有名管道的全路径名;mod为创建的有名管道的模式,指明其存取权限;dev为设备值,该值取决于文件创建的种类,只在创建设备文件时才会用到。若函数成功调用,则返回0,否则返回-1。
mknod()使用示例如下:
【例9-6】进程通信。
本例利用管道实现进程通信。
设计步骤
1)在Vim中创建一个新工程文件,命名为“pipeS.c”。
2)在“pipeS.c”中创建的代码如下所示。
代码实例创建了父子进程。父进程写管道,子进程读管道。子进程读一次管道就休眠1s,父进程一次写操作后将阻塞,直到子进程取走数据。父进程的写一次管道后休眠1s,子进程一次读操作后将阻塞,直到父进程再次写数据。如果管道内的实际数据比请求读的要少,读不阻塞。该程序用GCC编译成可执行文件pipeS后,在终端上运行./pipeS,进程通信结果如图9-12所示。
图9-12 进程通信结果
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。