在Linux fork期间防止文件描述符继承

如何防止跨fork()系统调用复制文件描述符(当然,不关闭文件描述符)?

我正在寻找一种方式来纪念 作为

(如果你喜欢这么FD_DONTINHERIT功能)通过孩子fork()的,有点像FD_CLOEXEC般的技巧,但对于叉。有人这样做吗?或对此进行了调查,对我有一个提示?

谢谢

更新:

我可以使用libc的__register_atfork

 __register_atfork(NULL, NULL, fdcleaner, NULL)

在fork()返回之前关闭child中的fds。但是,fds仍在被复制,因此对我来说这听起来像是一个愚蠢的破解。问题是如何跳过不需要的fds的子项中的dup()-ing

我在想一些需要fcntl(fd,F_SETFL,F_DONTINHERIT)的场景:

  • fork()将复制事件fd(例如epoll);有时这是不需要的,例如FreeBSD将kqueue()事件fd标记为KQUEUE_TYPE,并且这些fds类型不会跨派复制(如果要复制kqueue fds,则显式跳过复制)从一个孩子使用它,它必须与共享的fd表进行分叉)

  • fork()会复制100k不需要的fds来分叉一个孩子来执行一些CPU密集型任务(假设对fork()的需求很低,并且程序员不希望为通常不会做的事情维护一个子级池)不会发生)

有些描述符我们要复制(0,1,2),有些(其中大多数?)不是。我认为完整的fdtable duping在这里是出于历史原因,但我可能是错的。

这听起来有多愚蠢:

  • 修补fcntl以支持 文件描述符 上的 dontinherit 标志(不确定是否应按fd或fdtable fd_set保留该标志,例如是否保留close-on-exec标志)
  • 修改内核中的dup_fd()以跳过 Dontinherit fds的复制,就像freebsd 对 kq fds所做的一样

考虑程序

#include <stdio.h>

#include <unistd.h>

#include <err.h>

#include <stdlib.h>

#include <fcntl.h>

#include <time.h>

static int fds[NUMFDS];

clock_t t1;

static void cleanup(int i)

{

while(i-- >= 0) close(fds[i]);

}

void clk_start(void)

{

t1 = clock();

}

void clk_end(void)

{

double tix = (double)clock() - t1;

double sex = tix/CLOCKS_PER_SEC;

printf("fork_cost(%d fds)=%fticks(%f seconds)\n",

NUMFDS,tix,sex);

}

int main(int argc, char **argv)

{

pid_t pid;

int i;

__register_atfork(clk_start,clk_end,NULL,NULL);

for (i = 0; i < NUMFDS; i++) {

fds[i] = open("/dev/null",O_RDONLY);

if (fds[i] == -1) {

cleanup(i);

errx(EXIT_FAILURE,"open_fds:");

}

}

t1 = clock();

pid = fork();

if (pid < 0) {

errx(EXIT_FAILURE,"fork:");

}

if (pid == 0) {

cleanup(NUMFDS);

exit(0);

} else {

wait(&i);

cleanup(NUMFDS);

}

exit(0);

return 0;

}

当然,不能认为这是一个真正的长凳,但是无论如何:

root@pinkpony:/home/cia/dev/kqueue# time ./forkit

fork_cost(100 fds)=0.000000ticks(0.000000 seconds)

real 0m0.004s

user 0m0.000s

sys 0m0.000s

root@pinkpony:/home/cia/dev/kqueue# gcc -DNUMFDS=100000 -o forkit forkit.c

root@pinkpony:/home/cia/dev/kqueue# time ./forkit

fork_cost(100000 fds)=10000.000000ticks(0.010000 seconds)

real 0m0.287s

user 0m0.010s

sys 0m0.240s

root@pinkpony:/home/cia/dev/kqueue# gcc -DNUMFDS=100 -o forkit forkit.c

root@pinkpony:/home/cia/dev/kqueue# time ./forkit

fork_cost(100 fds)=0.000000ticks(0.000000 seconds)

real 0m0.004s

user 0m0.000s

sys 0m0.000s

forkit在2.20GHz,4GB内存的Dell Inspiron 1520Intel®Core 2 Duo CPU T7500上运行;平均负载=

0.00

回答:

不。您自己关闭它们,因为您知道哪些需要关闭。

以上是 在Linux fork期间防止文件描述符继承 的全部内容, 来源链接: utcz.com/qa/419535.html

回到顶部