进程在结束的时候,不管是异常退出还是正常退出,还是exit或是return终止进程,进程所占用的内存资源都会被操作系统回收,成不了zombie。
而线程和子进程不一样,必须要有exit的函数对其进行处理,否则会造成内存泄露。另外,只有运行的进程才有内存泄露问题。
转载一篇别人和一个ChinaUNIX上关于这个讨论 http://bbs.chinaunix.net/thread-3648464-1-1.html
http://www.cnblogs.com/daniagger/archive/2012/07/04/2576265.html
wait函数的一些问题
1 #include <sys/wait.h> 2 3 //若成功则返回进程ID,若出错则返回-1 4 pid_t wait(int *statloc); 5 6 pid_t waitpid(pid_t pid,int *statloc,int options);
当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号。因为子进程终止是一个异步事件,所以这种信号也是内核向父进程发送的异步通知。父进程可以选择忽略该信号,或者提供一个该信号发生时即被调用执行的函数(信号处理程序)。对这种信号的默认动作是忽略它。
对任一终止情形,我们都希望终止进程能够通知其父进程它是如何终止的。该终止进程的父进程都能用wait或waitpid函数取得其终止状态。
我们呢区分退出状态和终止状态。退出状态是传向exit或_exit的参数,或main的返回值。
调用wait或waitpid有三种不同的情况发生:
1、如果其所有子进程都还在运行,则阻塞
2、如果一个子进程终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回
3、如果它没有任何子进程,则立即出错返回
如果进程由于接收到SIGCHLD信号而调用wait,则可期望wait会立即返回,但是如果在任意时刻调用wait,则进程可能会阻塞。
在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞。
waitpid并不等待在其调用之后的第一个终止子进程,他有若干选项,可以控制他所等待的进程。
如果statloc不是一个空指针,则终止进程的终止状态就存放在他所指向的单元内。
waitpid函数提供wait函数没有提供的三个功能:
1、waitpid可等待一个特定的进程,而wait则返回任一终止子进程的状态
2、waitpid提供了一个wait的非阻塞版本
3、waitpid支持作业控制
一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息,释放它仍占有的资源)的进程被成为僵尸进程(zombie)。
如果一个进程fork一个子进程,但不要它等待子进程终止,也不希望子进程处于僵尸状态直到父进程终止,实现这一要求的技巧是调用fork两次。
当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,我们认为发生了竞争条件(race condition)。
如果一个进程希望等待一个子进程终止,则它必须调用一个wait函数;如果一个进程要等待其父进程终止,则可使用下列形式的循环:
1 while(getppid()!=1) 2 sleep(1);
这种轮询(polling)浪费了CPU时间。为了避免竞争条件和轮询,在多个进程之间需要有某种形式的信号发送和接收的方法。可以使用信号机制或者进程间通信(IPC)。