当进程间可以共享数据, 并且可以等待其他进程是否执行完毕时, 程序将变得更加强大.
显然共享数据和等待都是内部进程通信的范畴, 这里主要讲一下 data stream.
每个进程都有一个descriptor table, 这个表包含了file descriptor(a number) 和 data stream的映射关系. 如图 :
默认会有3条映射关系, 0, 1 , 2 分别代表stdin, stdout, stderr.
这里的映射关系可以通过dup2 系统函数来修改, 例如要把database connection 这个data stream放到1对应的data stream上. 执行 dup2(3,1) .
当使用open打开一个文件的时候, 会在descriptor table里面寻找有没有空的slot, 找到数值最小的空闲slot, 然后在这个file descriptor上建立一条映射. 这个descriptor table最大可以存储255条映射.
在命令行中使用> <进行重定向时 , 例如 :
1>? 表示标准输出重定向到?,
2>?表示标准错误重定向到?.
还可以使用&1,&2.
例如2>? 1>&2 表示标准错误重定向到?, 并且标准输出重定向到标准错误.
接下来这个程序使用fopen创建一个文件数据流, 并使用dup2将这个数据流放置到 file descriptor= 1 (也就是stdout) 的条目上. 然后往stdout和这个file data stream分别写入一条消息. 看看是不是都会写入同一个文件.
编译 :
执行 :
使用fprintf写入 stdout和my_file 都写到了/tmp/my_file.log
下面穿插一个 fork 和 waitpid 的使用场景.
为什么主进程要等待子进程执行完毕呢?
来看个例子 :
没有任何内容, 因为子进程还在执行, 并没有往/tmp/my_file.log写入任何信息.
等待100秒后再次查看这个文件的内容就有了.
像这种场景, 如果主进程等待子进程执行结束则不会发生误解.
修改代码如下 :
如果waitpid等待的进程号不是子进程的进程号会怎么样呢?
【参考】
dup, dup2 :
wait, waitpid
fopen
fclose
fsync, fdatasync
exit
fileno