做网站怎么那么难,移动端的网站怎么做的,扬州市建设工程造价管理站网站,怎么开发自己的小程序#include sys/types.h
#include sys/wait.h pid_t wait(int *status); 僵尸进程。进程结束后放弃了几乎所有的内存空间#xff0c;没有任何可以执行的代码#xff0c;也不能被调度#xff0c;仅仅在进程列表中保留着一个位置#xff0c;记载着该进程的退出…#include sys/types.h
#include sys/wait.h pid_t wait(int *status); 僵尸进程。进程结束后放弃了几乎所有的内存空间没有任何可以执行的代码也不能被调度仅仅在进程列表中保留着一个位置记载着该进程的退出状态等信息供其他进程收集除此之外僵尸进程不再占有任何内存空间。
当进程终止时操作系统的隐式回收机制会1.关闭所有文件描述符 2. 释放用户空间分配的内存。内核的PCB仍存在。其中保存该进程的退出状态此时是一个僵尸进程。正常终止→退出值异常终止→终止信号
一个进程在终止时会关闭所有文件描述符释放在用户空间分配的内存但它的PCB还保留着内核在其中保存了一些信息如果是正常终止则保存着退出状态如果是异常终止则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait或waitpid获取这些信息然后彻底清除掉这个进程。
在shell终端执行的命令和程序都是shell通过fork产生的子进程来完成的因此在命令和程序结束后shell终端进程也可以获取子进程的结束状态通过特殊命令$?查看如果为0表示正常结束如果为非0值表示出现了错误。Shell调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。
父进程调用wait函数可以回收子进程终止信息。该函数有三个功能1.阻塞等待子进程退出父进程调用该函数后如果子进程没死则父进程阻塞并等待子进程结束2. 获取子进程结束状态退出原因3.回收子进程残留资源 回收子进程结束后残留在内核中的PCB资源然后彻底清除掉这个进程。
进程的一生。随着fork的成功执行一个新的子进程产生但此时它还只是父进程的克隆。然后随着exec函数族新进程脱胎换骨开始独立执行一个全新的程序并完全替代了原有的父进程。进程结束可以是自杀也可以是他杀。自杀遇到main函数的最后一个“}”、在main函数中使用return或者调用exit和_exit他杀被其它进程通过另外一种方式杀掉。进程自杀属于正常死亡即使程序出错但是进程自身结束了自己可以通过return和exit赋给进程结束后一个值通过wait或waitpid函数来获取该值从而知道该进程自杀的原因是否出错一般0代表正常非0代表出错当然可以返回任何值由wait函数可以获取到。进程如果属于他杀则为异常结束在linux操作系统中所有的异常终止都是由于某一个信号导致的通过kill –l参数可以查看所有的信号及信号编号如在程序中给一个常量赋值会发生段错误此时进程会收到段错误相应的信号从而被终止除数为0时进程也会收到一个信号浮点数例外从而被终止。而终止进程的信号会记录在终止信息中供父进程调用wait函数获取。进程死掉后会留下一具僵尸wait和waitpid则去收集信息清理尸体。
exit和_exit这两个函数都是系统调用都有一个整型形参用于传递进程结束时的状态正常结束还是出错结束。一般0表示正常结束非0值如1表示出现了错误非正常结束。可以利用wait系统调用接收子进程的返回值从而针对不同的情况进行不同的处理。 pid_t wait(int *status);
status为传出参数用于获取子进程结束时的状态原因。函数执行成功则返回清理掉的子进程ID如果失败则返回-1。进程一旦调用了wait就立即阻塞自己由wait自动分析该进程的某个子进程是否已经退出如果找到了一个已经结束的子进程则收集其信息并将其清除掉并返回该子进程ID如果没有找到这样的一个子进程则会一直阻塞到那里直到有一个出现为止。如果父进程没有子进程则直接返回-1表示出错。
如果对子进程如何死掉的不关心不需要收集其残留的信息只想把僵尸进程消灭掉可以将函数形参设置为NULL即pidwait(NULL); 可使用wait函数传出参数status整型值来保存进程的退出状态。借助宏函数来进一步判断进程终止的具体原因。宏函数可分为如下三组 1. WIFEXITED(status) 为非0 → 表示进程正常结束
WEXITSTATUS(status) 如上宏为真进程正常结束使用此宏 → 获取进程退出状态 (exit/_exit/return的参数) 2. WIFSIGNALED(status) 为非0 → 表示进程异常终止 WTERMSIG(status) 如上宏为真使用此宏 → 取得使进程终止的那个信号的编号。可以通过kill –l命令查看编号的详细含义。
3. WIFSTOPPED(status) 为非0 → 表示进程处于暂停状态进程没有终止只是暂停运行如挂起或阻塞。
WSTOPSIG(status) 如上宏为真使用此宏 → 取得使进程暂停的那个信号的编号。
WIFCONTINUED(status) 为真 → 进程暂停后已经继续运行 //代码举例
#include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/wait.h
#include unistd.hint main(void)
{pid_t pid, wpid;int status;pid fork( );if(pid 0){printf(---child, my parent %d, going to sleep 10s\n,getppid( ));sleep(10);printf(-------------child die--------------\n);exit(77); //return 77; _exit(77); //子进程正常结束置其结束状态为77}else if(pid 0){wpid wait(status); //父进程阻塞等待子进程结束if(wpid-1){perror(wait);exit(1); //置结束状态为1}if( WIFEXITED(status) ) //如果子进程正常结束{printf( The child process exit with %d\n,WEXITSTATUS(status));}else if( WIFSIGNALED(status) ) //如果子进程异常结束{printf( The child process was killed by %dth signal\n,WTERMSIG(status));}while (1){printf(I am parent, pid %d, myson %d\n, getpid(), pid);sleep(1);} //父进程一直运行}else{perror(fork);exit(1);}return 0;
}
[rootlocalhost wait]# ./wait_test
---child, my parent 30770, going to sleep 10s
-------------child die--------------
The child process exit with 77 //获取了结束状态为77
I am parent, pid 30770, myson 30771
I am parent, pid 30770, myson 30771
I am parent, pid 30770, myson 30771
[rootlocalhost wait]#ps aux
root 30770 0.0 0.0 4164 356 pts/0 S 18:11 0:00 ./wait_test
root 30791 0.0 0.0 123360 1380 pts/2 R 18:12 0:00 ps aux
可见只有父进程在一直运行子进程不存在了也不存在僵尸进程子进程痕迹被完全清除。 在子进程运行期间利用kill -9 将其杀掉则为异常结束
[rootlocalhost wait]#ps aux
[rootlocalhost wait]# kill 30830
[rootlocalhost wait]# ./wait_test
---child, my parent 30829, going to sleep 60s
The child process was killed by 15th signal
I am parent, pid 30829, myson 30830
I am parent, pid 30829, myson 30830
I am parent, pid 30829, myson 30830
I am parent, pid 30829, myson 30830
利用kill -l 命令可以查看编号为15的信号为 15) SIGTERM 总结进程正常结束父进程利用wait函数回收其结束状态状态值通过return、exit和_exit返回一般如果程序正常则为0出错设非0但不是必须的如果进程结束没有指明其值如main函数中没有return语句且正常结束则会有默认值正常0出错非0。注意return、exit和_exit返回的值必须不超过128可通过wait函数获取。如果函数异常结束wait函数回收其终止原因信号编号。