从派生的子进程返回后的文件指针 [英] File pointers after returning from a forked child process

查看:88
本文介绍了从派生的子进程返回后的文件指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于分叉的父进程和子进程之间共享的给定文件描述符,在子进程从同一文件描述符读取后,父进程中的文件位置保持不变是正常的吗?

Is it normal, for a given file descriptor shared between a forked parent and child process, that the file position in the parent process remains the same after a child process reads from the same file descriptor?

这对我来说正在发生.这是设置:

This is happening for me. Here's the setup:

我正在编写一个C ++ CGI程序,因此它从stdin读取http请求.在处理multipart_form时,我使用具有getc()方法的中间对象(Multipart_Pull)处理stdin,该方法检测边界字符串并在每个字段的末尾返回EOF,因此我可以假装字段的内容是文件.当该字段是文件上载时,我分叉两次以将Multipart_Pull :: getc的结果传递到运行ssconvert的子进程的stdin上,该子进程从Excel文件制作CSV文件以进行进一步处理.我编写了子进程,以将文件指针留在父进程可以拾取它的位置.父进程使用wait()来确保子进程在继续之前完成.

I am writing a C++ CGI program, so it reads http requests from stdin. When processing a multipart_form, I process stdin with an intermediary object (Multipart_Pull) that has a getc() method that detects the boundary strings and returns EOF at the end of a each field, so I can pretend a field's contents are a file. When the field is a file upload, I fork twice in order to pipe the results of Multipart_Pull::getc to the stdin of a child process that runs ssconvert to make a CSV file from an Excel file for further processing. I wrote the child process to leave the file pointer at the position where the parent could pick it up. The parent process uses wait() to ensure the child processes are done before continuing.

为了在开发Multipart_Pull时进行测试,我通过打开从真实multipart_form请求复制的磁盘文件来伪造stdin.

For testing while developing Multipart_Pull, I am faking stdin by opening a disk file that was copied from a real multipart_form request.

伪造stdin时,子进程返回后,父进程中读取的第一个字符与子进程启动时读取的第一个字符相同.也就是说,文件指针没有在父文件的副本中移动.

When faking stdin, and after the child process returns, the first character read in the parent process is the same first character that the child process read when it started. That is, the file pointer didn't move in the parent's copy of the file.

我已经确认子进程实际上是通过运行gdb并通过使用set follow-fork-mode child跟随相应的子进程来读取数据的,并且还通过将读取的字符与从中读取的字符进行比较来确认返回时父文件的文件位置数据被读取.

I have confirmed that the child process actually reads the data by running gdb and following the appropriate child process by using set follow-fork-mode child, and also confirmed the file position of the parent on return by comparing the characters read against the file from which the data is read.

当我真正从stdin中读取内容时,我并不希望这会成为问题,因为(如果我错了,请纠正我),当您从stdin中读取一个字符时,它就永远消失了.

When I am really reading from stdin, I don't expect that this will be a problem because (correct me if I'm wrong here), when you read a character from stdin, it's gone forever.

我意识到有解决此特定问题的方法,最简单的方法是忽略在multipart_form上上传文件之后的任何字段,即,父级不尝试在fork之后继续读取.但是,我不想削弱生产代码或进行不必要的限制,主要是因为我真的只想了解发生了什么.

I realize that there are workarounds to solve this particular problem, the easiest being to just ignore any fields that follow a file upload on a multipart_form, i.e. the parent doesn't try to continue reading after the fork. However, I hate to cripple the production code or make unnecessary restrictions, and mainly because I really just want to understand what's happening.

谢谢.

推荐答案

对于在派生的父子进程之间共享的给定文件描述符,在子进程从同一文件描述符读取后,父进程中的文件位置保持不变是正常的吗?

Is it normal, for a given file descriptor shared between a forked parent and child process, that the file position in the parent process remains the same after a child process reads from the same file descriptor?

自从您提出fork()以来,我假设您正在使用符合POSIX的系统.否则,答案取决于您的C ++实现的具体细节.

Since you bring up fork(), I presume you are working with a POSIX-compliant system. Otherwise, the answer is subject to the specific details of your C++ implementation.

在POSIX术语中,文件描述符和流都是基础打开文件描述"上的句柄"类型.同一打开文件描述上可能有多个不同的句柄,它们可能由不同的进程持有. fork()函数是发生这种情况的一种方式.

In POSIX terminology, file descriptors and streams are both types of "handles" on an underlying "open file description". There may be multiple distinct handles on the same open file description, potentially held by different processes. The fork() function is one way in which such a situation may arise.

如果操纵了同一打开文件描述上的多个句柄,则POSIX会明确声明未指定结果,除非

In the event that multiple handles on the same open file description are manipulated, POSIX explicitly declares the results unspecified except under specific conditions. Your child processes satisfy their part of those requirements by closing their streams, either explicitly or as a consequence of normal process termination. According to POSIX, however, for the parent's subsequent use of its stream to have specified behavior, it "shall perform an lseek() or fseek() (as appropriate to the type of handle) to an appropriate location."

换句话说,父进程不能依靠子进程对文件偏移量的操作使其自动可见,并且实际上,在子进程操纵流的副本之后,根本就不能依赖任何特定的偏移量.

In other words, the parent process cannot rely on the child processes' manipulation of the file offset to automatically be visible to it, and in fact cannot rely on any particular offset at all after the children manipulate their copies of the stream.

这篇关于从派生的子进程返回后的文件指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆