主进程退出后子进程还能正常工作吗?

时间:2021-08-03 23:48:45
以下一段代码请帮忙分析一下:
cdmachange是另一个程序,它的参数不用管了。
主进程创建了三个子进程后退出。子进程各启动一个cdmachange程序。
如果主进程工作完毕后退出。三个子进程还能成功启动cdmachange程序吗?

for(i=0;i<3;i++)
{
    /*创建预处理子进程*/
    if((pid = fork()) <0)
    {
        /*创建预处理子进程失败处理不用管它*/
        exit(0);
    }
    if(pid == 0)/*子进程*/
    {
        /*执行子程序*/
        if (execl("cdmachange","cdmachange",
            ini_array->city_code[i],shmid_buf,(char*)0)<0) 
        {
            /*调用cdmachange程序失败不用管它*/
            exit(1);
        } 
        exit(0);
     }
}
printf("程序启动完毕,主进程退出!\n");
exit(0);

15 个解决方案

#1


你没有搞清楚execl的执行后的处理结果,如果execl执行成功后,你的子进程就消失了,被cdmachange代替了,呵呵

#2


用fork产生子进程,父进程先结束或子进程先结束,是不一定的。把第二个exit(0)去掉。

#3


execl我确实没搞懂。前面两位的意思是:成功调用了execl后,它后面的代码就不会在被执行。即使调用cdmachange程序已经返回或退出,execl后面的语句也不会执行。
新问题:
1.如果cdmachange程序中是用return返回的,是不是子进程就不会结束,一直挂着。
2.父进程的结束与否不影响子进程吗?如果kill掉父进程子进程会怎么样呢?

#4


还有一个方法:你将主进程设计为一个管理任务(周期,其余时间睡眠)
这样就可以了。

#5


强烈建议:看看Windows 核心编程第二部分—4章以后的内容。

#6


不能 子进程将退出

#7


fork - exec结构是最传统的unix/linux程序调用方法,在命令行上输入一个命令之后,shell就fork一个自己,这个子shell再exec你的命令,于是命令被执行。exec 和 system 是两个不同的系统调用,区别在于system不覆盖fork的shell,exec族的则覆盖。看看unix的书籍有所帮助。

#8


还有典型的案例就是client/server结构,传统方式也是基于fork - exec的,
如果listen到一个连接
accept
fork自己
if( 0 == fork )
   exec 处理过程文件
else
   继续监听

#9


还是对execl不清楚,execl也会创建进程,但它不是向fork那样复制父进程,而是用自己的代码将创建他的父进程的空间全部替换,这时其父进程已经不存在了,父进程变成了原来调用fork的进程,当然你继续使用kill命令当然可以结束execl创建的进程,因为进程id号丙没有改变,附进程结束也不会影响你的子进程,只不过子进程变成了孤孩进程被你的系统的init进程收养了。呵呵

#10


再问一个:
1.我在子进程的if语句前加了一个sleep(30) 在主进程的for循环之后加了sleep(15) 。假设该程序名称为inchange,启动inchange程序后,有四个inchange进程。立刻kill掉了主进程,但是仍然有三个inchange子进程在工作。30秒后变为cdmachange进程在工作。为何子进程不死呢?
2.另:cdmachange程序return之后。检测进程是高诉我以下信息:8659,8660,8661,三个进程死了怎么还显示呢?cdmachange程序要怎么样退出才合理?
ps -u maex
   PID TTY      TIME CMD
  8661          0:00 <defunct>
 14833 pts/26   0:00 csh
  8659          0:00 <defunct>
  8660          0:00 <defunct>

#11


父进程要waitpid等子进程退了再退,或者fork两次,让子进程成为init的孤儿进程

#12


kill掉父进程不一定导致子进程退出。如果需要,应该kill掉的是进程组。


fork是将当前进程复制,并且在调用点分叉。
execl则会用被调用程序的代码来覆盖当前进程,当然,当前进程的正文就没有了。spawn函数族则不会覆盖。
execl出来的代码,会继承原来进程的进程号,父进程也不会改变。如果父进程结束,那么子进程将会被init接管。也就是父进程的进程号变成1。
如果子进程结束,父进程还在运行,那么,系统会保存子进程的退出状态,并给父进程一个SIGCHILD信号。这时候父进程应该响应该信号,并且调用waitpid,让系统释放子进程。这和子进程采用什么样的退出方式没有关系。

#13


多谢各位

#14


to unix_socket()
你产生了僵尸进程就是后面带<defunct>的.
你应该捕获子进程退出的时候产生的SIGCLD信号,不能够忽略他,否则的话,子进程就会变成僵尸进程.这样的话非常耗系统的资源的.

#15


同意楼上

#1


你没有搞清楚execl的执行后的处理结果,如果execl执行成功后,你的子进程就消失了,被cdmachange代替了,呵呵

#2


用fork产生子进程,父进程先结束或子进程先结束,是不一定的。把第二个exit(0)去掉。

#3


execl我确实没搞懂。前面两位的意思是:成功调用了execl后,它后面的代码就不会在被执行。即使调用cdmachange程序已经返回或退出,execl后面的语句也不会执行。
新问题:
1.如果cdmachange程序中是用return返回的,是不是子进程就不会结束,一直挂着。
2.父进程的结束与否不影响子进程吗?如果kill掉父进程子进程会怎么样呢?

#4


还有一个方法:你将主进程设计为一个管理任务(周期,其余时间睡眠)
这样就可以了。

#5


强烈建议:看看Windows 核心编程第二部分—4章以后的内容。

#6


不能 子进程将退出

#7


fork - exec结构是最传统的unix/linux程序调用方法,在命令行上输入一个命令之后,shell就fork一个自己,这个子shell再exec你的命令,于是命令被执行。exec 和 system 是两个不同的系统调用,区别在于system不覆盖fork的shell,exec族的则覆盖。看看unix的书籍有所帮助。

#8


还有典型的案例就是client/server结构,传统方式也是基于fork - exec的,
如果listen到一个连接
accept
fork自己
if( 0 == fork )
   exec 处理过程文件
else
   继续监听

#9


还是对execl不清楚,execl也会创建进程,但它不是向fork那样复制父进程,而是用自己的代码将创建他的父进程的空间全部替换,这时其父进程已经不存在了,父进程变成了原来调用fork的进程,当然你继续使用kill命令当然可以结束execl创建的进程,因为进程id号丙没有改变,附进程结束也不会影响你的子进程,只不过子进程变成了孤孩进程被你的系统的init进程收养了。呵呵

#10


再问一个:
1.我在子进程的if语句前加了一个sleep(30) 在主进程的for循环之后加了sleep(15) 。假设该程序名称为inchange,启动inchange程序后,有四个inchange进程。立刻kill掉了主进程,但是仍然有三个inchange子进程在工作。30秒后变为cdmachange进程在工作。为何子进程不死呢?
2.另:cdmachange程序return之后。检测进程是高诉我以下信息:8659,8660,8661,三个进程死了怎么还显示呢?cdmachange程序要怎么样退出才合理?
ps -u maex
   PID TTY      TIME CMD
  8661          0:00 <defunct>
 14833 pts/26   0:00 csh
  8659          0:00 <defunct>
  8660          0:00 <defunct>

#11


父进程要waitpid等子进程退了再退,或者fork两次,让子进程成为init的孤儿进程

#12


kill掉父进程不一定导致子进程退出。如果需要,应该kill掉的是进程组。


fork是将当前进程复制,并且在调用点分叉。
execl则会用被调用程序的代码来覆盖当前进程,当然,当前进程的正文就没有了。spawn函数族则不会覆盖。
execl出来的代码,会继承原来进程的进程号,父进程也不会改变。如果父进程结束,那么子进程将会被init接管。也就是父进程的进程号变成1。
如果子进程结束,父进程还在运行,那么,系统会保存子进程的退出状态,并给父进程一个SIGCHILD信号。这时候父进程应该响应该信号,并且调用waitpid,让系统释放子进程。这和子进程采用什么样的退出方式没有关系。

#13


多谢各位

#14


to unix_socket()
你产生了僵尸进程就是后面带<defunct>的.
你应该捕获子进程退出的时候产生的SIGCLD信号,不能够忽略他,否则的话,子进程就会变成僵尸进程.这样的话非常耗系统的资源的.

#15


同意楼上