我正在开发一个在 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/