C - 如何查找先前由 tmpfile() 创建的临时文件?

发布于 2024-08-06 03:30:54 字数 233 浏览 3 评论 0原文

我正在开发一个多进程程序,该程序基本上对 RVB 文件的每一层执行模糊化。 (1个过程->1层)。每个子进程都使用以下函数传递临时文件:tmpfile()。每个子进程完成其工作后,主进程必须读取创建的每个临时文件并组装数据。问题是我不知道如何读取主进程内的每个临时文件,因为我无法访问子进程内存,所以我不知道指向创建的临时文件的临时指针是什么!

有什么想法吗?

如果需要,请随时要求澄清。

I'm working on a multi-process program which basically perform fuzzification on each layer of a RVB file. (1 process -> 1 layer). Each child process is delivering a temp file by using the function: tmpfile(). After each child process finishes its job, the main process has to read each temp file created and assemble the data. The problem is that I don't know how to read each temp file inside the main process since I can't access to child's process memory so I can't know what's the temporary pointer to the temp file created!

Any idea?

Don't hesitate to ask for clarifications if needed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

怂人 2024-08-13 03:30:54

tmpfile() 函数返回一个 FILE 指针,指向一个没有确定名称的文件 - 事实上,即使子进程也无法轻易确定该文件的名称,更不用说父文件(在许多 Unix 系统上,该文件没有名称;在 tmpfile() 返回给调用者之前它已取消链接)。

extern FILE *tmpfile(void);

因此,如果您必须传递文件名,则您使用了错误的临时文件创建原语。

您有多种选择:

  1. 让父进程使用 tmpfile() 创建文件流,以便父进程和子进程共享文件。有一些小的协调问题需要处理 - 父母在阅读孩子们写的内容之前需要回到开头,并且只能在孩子退出后才这样做。
  2. 使用文件名生成原语之一 - mkstemp() 很好,如果您需要 FILE 指针而不是文件描述符,则可以使用 fdopen() 来创建一。您仍然面临着从子级到父级获取文件名的问题;同样,父级可以打开文件,或者您可以为每个子级使用一个管道,或者一些共享内存,或者......选择 IPC 机制。
  3. 在分叉之前,让父级为每个子级打开一个管道。子进程关闭管道的读端,并向写端写入;父级关闭管道的写入端并安排从读取端读取。这里有多个子项的问题是任何给定管道的容量都是有限的(而且非常小 - 通常约为 5 KiB)。因此,您需要确保父级完全读取所有管道,并记住,在读取所有数据之前,子级将无法退出(严格来说,除了最后一个缓冲区已满之外的所有数据都已被读取)。
  4. 考虑使用线程 - 但要注意使用线程的协调问题。
  5. 确定您不需要使用多个控制线程(无论是进程还是线程),而只需让主程序完成工作即可。这消除了协调和 IPC 问题 - 这确实意味着您不会从机器上的多核处理器中受益。

其中,假设并行执行至关重要,我可能会使用管道从子级获取文件名(选项 2);它的协调问题最少。但为了简单起见,我会选择“主程序完成这一切”(选项 5)。

The tmpfile() function returns you a FILE pointer to a file with no determinate name - indeed, even the child process cannot readily determine a name for the file, let alone the parent (and on many Unix systems, the file has no name; it has been unlinked before tmpfile() returns to the caller).

extern FILE *tmpfile(void);

So, you are using the wrong temporary file creation primitive if you must convey file names around.

You have a number of options:

  1. Have the parent process create the file streams with tmpfile() so that both the parent and children share the files. There are some minor coordination issues to handle - the parent will need to seek back to the start before reading what the children wrote, and it should only do that after the child has exited.
  2. Use one of the filename generating primitives instead - mkstemp() is good, and if you need a FILE pointer instead of a file descriptor, you can use fdopen() to create one. You are still faced with the problem of getting file names from children to parent; again, the parent could open the files, or you can use a pipe for each child, or some shared memory, or ... take your pick of IPC mechanisms.
  3. Have the parent open a pipe for each child before forking. The child process closes the read end of the pipe and writes to the the write end; the parent closes the write end of the pipe and arranges to read from the the read end. The issue here with multiple children is that the capacity of any given pipe is finite (and quite small - typically about 5 KiB). Consequently, you need to ensure the parent reads all the pipes completely, bearing in mind that the children won't be able to exit until all the data has been read (strictly, all but the last buffer full has been read).
  4. Consider using threads - but be aware of the coordination issues using threads.
  5. Decide that you do not need to use multiple threads of control - whether processes or threads - but simply have the main program do the work. This eliminates coordination and IPC issues - it does mean you won't benefit from the multi-core processor on the machine.

Of these, assuming parallel execution is of paramount importance, I'd probably use pipes to get the file names from the children (option 2); it has the fewest coordination issues. But for simplicity, I'd go with 'main program does it all' (option 5).

疯狂的代价 2024-08-13 03:30:54

如果您在父进程中调用 tmpfile() ,子进程将继承所有打开的描述符,并且能够写入文件,并且父进程也可以访问打开的文件。

If you call tmpfile() in parent process, child will inherit all open descriptors and will be able to write to the file, and opened file will be accessible for parent as well.

粉红×色少女 2024-08-13 03:30:54

您可以在父进程中创建一个临时文件,然后分叉,然后让子进程使用它。

You could create a tempfile in the parent process and then fork, then have the child process use that.

逆光下的微笑 2024-08-13 03:30:54

子进程可以将文件描述符发送回父进程。

编辑: APUE 站点中的示例代码(src.tar.gz/apue.2e/lib,recvfd.c 、sendfd.c)

The child process can send back the filedescriptor to the parent process.

EDIT: example code in APUE site (src.tar.gz/apue.2e/lib, recvfd.c, sendfd.c)

枕头说它不想醒 2024-08-13 03:30:54

使用线程而不是子进程?将临时文件的名称放在另一个文件中?不要对临时文件使用随机名称,而是(例如)基于父进程的 pid 的名称(以允许程序的多个实例同时运行)加上序列号?

Use threads instead of subprocesses? Put the names of the temporary files in another file? Don't use random names for the temp files, but (for example) names based on the pid of the parent process (to allow several instances of your program to run simultaneously) plus a sequential number?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文