首先程序创建了一个命名管道用来写入数据:
mkfifo(pipeName, 0666); /* read/write perms for user/group/others */ int fd = open(pipeName, O_CREAT | O_WRONLY);
其中的 pipeName 是备份文件的名字,传递给 mkfifo 作为它的第一个参数。接着命名管道通过我们熟悉的 open 函数调用被打开,而这个函数将会返回一个文件描述符。
在实现层面上,fifoWriter 不会一次性将所有的数据都写入,而是写入一个块,然后休息随机数目的微秒时间,接着再循环往复。总的来说,有 768000 个 4 字节整数值被写入到命名管道中。
在关闭命名管道后,fifoWriter 也将使用 unlink 取消对该文件的连接。
close(fd); /* close pipe: generates end-of-stream marker */ unlink(pipeName); /* unlink from the implementing file */
一旦连接到管道的每个进程都执行了 unlink 操作后,系统将回收这些备份文件。在这个例子中,只有两个这样的进程 fifoWriter 和 fifoReader ,它们都做了 unlink 操作。
这个两个程序应该在不同终端的相同工作目录中执行。但是 fifoWriter 应该在 fifoReader 之前被启动,因为需要 fifoWriter 去创建管道。然后 fifoReader 才能够获取到刚被创建的命名管道。
示例 3. fifoReader 程序
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> -
-
unsigned is_prime(unsigned n) { /* not pretty, but gets the job done efficiently */ if (n <= 3) return n > 1; if (0 == (n % 2) || 0 == (n % 3)) return 0; -
unsigned i; for (i = 5; (i * i) <= n; i += 6) if (0 == (n % i) || 0 == (n % (i + 2))) return 0; -
return 1; /* found a prime! */ } -
int main() { const char* file = "./fifoChannel"; int fd = open(file, O_RDONLY); if (fd < 0) return -1; /* no point in continuing */ unsigned count = 0, total = 0, primes_count = 0; -
while (1) { int next; int i; ssize_t count = read(fd, &next, sizeof(int)); -
if (0 == count) break; /* end of stream */ else if (count == sizeof(int)) { /* read a 4-byte int value */ total++; if (is_prime(next)) primes_count++; } } -
close(fd); /* close pipe from read end */ unlink(file); /* unlink from the underlying file */ [printf][10]("Received ints: %u, primes: %u\n", total, primes_count); -
return 0; }
上面的 fifoReader 的内容可以总结为如下:
|