c - 在 fork() child 中继承父套接字

标签 c linux multithreading sockets fork

我正在开发一个在 linux 系统(内核 3.4.11)上运行的 C 应用程序

在我的应用程序中,我在一个线程上打开一个服务器套接字。我正在打开一个 fork(),在其中我在主线程中使用 execvp() 执行 shell 命令。

打开一个fork() 将继承子进程中的套接字文件描述符。根据网络上的许多主题,这可能会导致问题。在我的例子中,如果我关闭我的应用程序,我可以通过 netstat 看到套接字已分配给另一个守护进程(另一个随机守护进程)。

其实对于这样的问题有很多解决方案:

1)fork() 子进程的开头关闭套接字:

if ((pid = fork()) == -1)
    return -1;

if (pid == 0) {
    /* child */

    close(socket_desc);

2) 在父级打开套接字时使用fcntl()FD_CLOEXEC

socket_desc = socket(AF_INET , SOCK_STREAM , 0);
fcntl(socket_desc, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);

3)socket()函数中使用O_CLOEXEC:

socket_desc = socket(AF_INET , SOCK_STREAM|O_CLOEXEC , 0);

什么是最好的解决方案?为什么?

欢迎任何其他更好的解决方案。

最佳答案

如果您控制所有代码,这些都没有区别。

如果别人给你一个你不知道它是如何创建的 socket,请使用第一个解决方案。

使用第二个,如果你编写了一个模块,其他人向你传输了一个套接字,并且你想将它传递给另一个你无法控制的模块,但你怀疑 fork()/exec().

如果您是套接字的创建者并且需要将其传递给您怀疑要fork()/exec() 的另一个模块,请使用第三个。

关于c - 在 fork() child 中继承父套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28341750/

相关文章:

linux - 通过 tee 发送到文件的转换流

java - 每隔几秒更新一次 android studio 中的 gps 位置

Java 线程池 : is it better to have lots of smaller tasks, 或更少的大批量任务

c - 如何在 execl() 函数中更改时区 (TZ=UTC) 输出。

c - C 中的数据包操作库

linux - ksh 的 getops 中的 |+ 运算符

c# - 处理器核心在 .net 平台中与生产者消费者一起使用多线程

c - OpenCL 无法为常量数组设置内核参数

C 语言 - 如何确保在读取多个输入文件时保持恒定格式?

c - 默认 `make` 行为从何而来?