在我的程序中,在这种情况下写入stderr时有时会冻结:
/proc/self/exe
读取)fprintf
写一些stderr
作品的尝试,在某些时候我将完全锁定我的程序。调试器告诉我它的fprintf。这里发生了什么?我已经尝试过将SIG_IGN
放在SIGPIPE
上,以防止程序在没有人再听管道时崩溃。但是现在我被卡住了(冻结的行为与SIG_IGN
相同,没有它)。
感谢任何帮助。
答案 0 :(得分:3)
简而言之:系统发送程序信号以避免出现问题。你忽略了这些信号。坏事发生了。
当你的父程序运行时,它有stdin(fd 0),stdout(fd 1)和stderr(fd 2)连接到运行你的shell(终端)的TTY。这些功能很像管道。关闭终端时,这些fds会悬空,另一侧没有人可以与他们通信。
起初,没有任何不好的事情发生。您写入stderr,标准库缓存这些写入。没有系统调用,所以没问题。
然后填充缓冲区,stdlib尝试刷新它们。当它这样做时,它会填充管道或TTY的内核缓冲区。起初,这也很好。然而,迟早,这些缓冲区也会填满。当发生这种情况时,内核会暂停您的进程并等待某人从这些管道的另一端读取。但是,由于您关闭了终端,所以没有人会这样做,并且您的程序会被无限期暂停。
避免此问题的标准方法是断开0-2文件描述符与控制TTY的连接。而不是告诉你如何做到这一点,我想建议你在这里尝试做什么,运行一个程序,以便它完全与TTY断开连接,有一个名字:daemonizing。
查看this问题,了解有关如何执行此操作的详细信息。
已编辑添加:
您的功能尚不清楚您execve
的节目是否是您自己的节目。如果不是,请注意许多用户程序不是作为守护程序运行的。最明显的警告是,如果未连接到任何TTY的程序打开TTY文件,并且除非它将O_NOCTTY
传递给open
,则该TTY将成为程序的控制TTY。视情况而定,可能会导致意外结果。