我做了制作叉子的程序,我认为孩子不影响父母.
但是文件指针已更改,但我没有对父进行任何更改.
#include
这输出
I'm one 21500 20
I'm two 21500 -1
我想让两个printf调用之间的文件指针不变.
为什么文件指针会改变,即使execvp失败,我也可以使文件指针不可更改?
虽然您的程序在CentOS 7 / GCC 4.8.5 / GLIBC 2.17上不会产生相同的意外行为,但您可能会观察到不同的行为.事实上你的程序的行为是根据POSIX(你依赖fork)来定义的.以下是the relevant section的一些摘录(重点补充):
An open file description may be accessed through a file descriptor,
which is created using functions such asopen()
orpipe()
,or through
a stream,which is created using functions such asfopen()
orpopen()
.
Either a file descriptor or a stream is called a “handle” on the open
file description to which it refers; an open file description may have
several handles.[…]
The result of function calls involving any one handle (the “active
handle”) is defined elsewhere in this volume of POSIX.1-2017,but if
two or more handles are used,and any one of them is a stream,the
application shall ensure that their actions are coordinated as
described below. If this is not done,the result is undefined.[…]
For a handle to become the active handle,the application shall ensure
that the actions below are performed between the last use of the
handle (the current active handle) and the first use of the second
handle (the future active handle). The second handle then becomes the
active handle. […]The handles need not be in the same process for these rules to apply.
Note that after a
fork()
,two handles exist where one existed before.
The application shall ensure that,if both handles can ever be
accessed,they are both in a state where the other could become the
active handle first. [Where subject to the preceding qualification,the] application shall prepare for afork()
exactly as if it were a change of active handle. (If the only action
performed by one of the processes is one of the exec functions or
_exit()
(notexit()
),the handle is never accessed in that process.)For the first handle,the first applicable condition below applies.
[An impressively long list of alternatives that do not apply to the OP’s situation …]
- If the stream is open with a mode that allows reading and the underlying open file description refers to a device that is capable of
seeking,the application shall either perform anfflush()
,or the
stream shall be closed.For the second handle:
- If any previous active handle has been used by a function that explicitly changed the file offset,except as required above for the
first handle,the application shall perform anlseek()
orfseek()
(as
appropriate to the type of handle) to an appropriate location.
因此,对于OP的程序来访问父级和子级中的相同流,POSIX要求父级fflush()stdin在分叉之前,并且子级fseek()在启动之后.然后,在等待子进程终止后,父进程必须fseek()流.但是,鉴于我们知道孩子的执行失败,可以通过让孩子使用_exit()(不访问流)而不是exit()来避免所有刷新和搜索的要求.
遵守POSIX的规定会产生以下结果:
When these rules are followed,regardless of the sequence of handles
used,implementations shall ensure that an application,even one
consisting of several processes,shall yield correct results: no data
shall be lost or duplicated when writing,and all data shall be
written in order,except as requested by seeks.
但值得注意的是
It is
implementation-defined whether,and under what conditions,all input
is seen exactly once.
我很欣赏,仅仅听到你对程序行为的期望没有得到相关标准的证明,这可能有点令人不满意,但实际上就是这样.父进程和子进程确实有一些相关的共享数据,这些共享数据采用公共开放文件描述的形式(它们具有相关的单独句柄),这似乎可能是意外(和未定义)行为的载体,但是没有预测您看到的特定行为的基础,以及我在同一程序中看到的不同行为.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。