Linux 为什么wineserver在后台运行时在子进程中设置主套接字?
当Wine服务器启动时,它通过open_master_socket()创建一个Unix套接字,以后启动的所有Wine进程都使用此套接字连接到Wine服务器,下面是server/request.c,open_master_socket()中的代码: acquire_lock()用于设置主套接字, 问题是,当在后台运行时,为什么fork()让子进程完成工作,而父进程只是等待并退出()? 为什么不在前台运行呢?“Linux 为什么wineserver在后台运行时在子进程中设置主套接字?,linux,sockets,wine,Linux,Sockets,Wine,当Wine服务器启动时,它通过open_master_socket()创建一个Unix套接字,以后启动的所有Wine进程都使用此套接字连接到Wine服务器,下面是server/request.c,open_master_socket()中的代码: acquire_lock()用于设置主套接字, 问题是,当在后台运行时,为什么fork()让子进程完成工作,而父进程只是等待并退出()? 为什么不在前台运行呢?“fork()并让子进程完成工作”是“在后台运行” 管道是一种习惯用法,它让父级留在周围,而
fork()
并让子进程完成工作”是“在后台运行”
管道是一种习惯用法,它让父级留在周围,而子级则进行可能失败的设置(在本例中,获取锁),并在发生故障时正确传播故障;否则,您无法轻松发现该子进程失败,但必须检查其是否存在,或随后扫描日志文件以查看是否出现问题。是的,Daemon多亏了ninjalj,这是一种实现后台运行守护程序的通用方法,并让分叉子代(守护程序)完成守护程序的工作。 使用_exit()而不是exit()的父级是为了避免意外删除临时文件。
有关守护进程的更多信息,请参阅 和
geekosaur很好地解释了为什么我们需要在退出()之前等待子进程。搜索“daemon”、“daemonize”。。。首先谢谢你的回答,但我还有一点不清楚:你的意思是如果它在foregroud中运行,我们可以看到从命令行退出吗?为什么进程不能传播失败本身?(子进程也称为exit()。这是服务器进程编程中的常见技巧吗?
exit()
将其状态传递给父进程。如果创建它的进程已退出,则该父进程是pid 1,init
,它通常无法报告有关失败进程的信息(有时除了syslog
)。此外,该子进程已切换到守护进程,因此它不再连接到可用于报告错误的终端(同样,它可能使用syslog
)。在初始启动期间,它可以使用此习惯用法在与创建它的会话完全分离之前向其父级报告错误,以便即使在会话退出后也可以运行。
771 if (!foreground)
772 {
773 if (pipe( sync_pipe ) == -1) fatal_perror( "pipe" );
774 pid = fork();
775 switch( pid )
776 {
777 case 0: /* child */
778 setsid();
779 close( sync_pipe[0] );
780
781 acquire_lock();
782
783 /* close stdin and stdout */
784 dup2( fd, 0 );
785 dup2( fd, 1 );
786
787 /* signal parent */
788 dummy = 0;
789 write( sync_pipe[1], &dummy, 1 );
790 close( sync_pipe[1] );
791 break;
792
793 case -1:
794 fatal_perror( "fork" );
795 break;
796
797 default: /* parent */
798 close( sync_pipe[1] );
799
800 /* wait for child to signal us and then exit */
801 if (read( sync_pipe[0], &dummy, 1 ) == 1) _exit(0);
802
803 /* child terminated, propagate exit status */
804 wait4( pid, &status, 0, NULL );
805 if (WIFEXITED(status)) _exit( WEXITSTATUS(status) );
806 _exit(1);
807 }
808 }
809 else /* remain in the foreground */
810 {
811 acquire_lock();
812 }