我有一个多线程应用程序,并且有办法做一个telnet,ssh到这个应用程序。在我的应用程序中,我使用下面的自定义system()调用重新启动一个init脚本。看起来,子进程仍然活跃。我这样说是因为如果我从telnet会话注销仍然会挂起进程,即它无法注销。仅当我使用此系统调用重新启动脚本时才会发生这种情况。我的system()函数有问题吗?
var eventCards = [
'Do1',
'Do2',
'Do3',
'Do4'
];
var eventDeck = new Deck(eventCards);
class Deck {
constructor(cards) {
this.cards = cards;
this.deck = shuffle(cards);
}
shuffle(array) {
...
}
drawTopCard() {
...
}
}
有关如何调试此系统调用是否被挂起的任何想法?
答案 0 :(得分:0)
我意识到这是因为文件描述符是在fork上继承的。 因为我的自定义系统()只是fork()和exec()。我的应用程序中有很多套接字。这些套接字文件描述符由子进程继承。
我的假设是“子进程无法退出,因为它正在等待父进程关闭文件描述符或那些文件描述符处于可以关闭的状态”。不知道那些州是什么。
所以,这是我发现的有趣链接 -
Call system() inside forked (child) process, when parent process has many threads, sockets and IPC
解决方案 -
linux fork: prevent file descriptors inheritance
不确定,我可以在一个大型应用程序中执行此操作,其中套接字在数千个位置打开。所以,这就是我所做的。
我的解决方案 -
我创建了一个单独的进程/守护进程,用于侦听来自父应用程序的命令。此通信基于套接字。因为,它是一个单独的应用程序/守护程序,它不会影响运行多个线程并且有很多打开的套接字的主应用程序。这对我有用。
我相信这个问题一旦解决就会解决 -
fcntl(fd,F_SETFD,FD_CLOEXEC);
欢迎任何评论。
Is this a fundamental problem in Linux, C i.e.
all file descriptors are inherited by default?
Why linux/kernel allow this? What advantage do we get out of it?