1、Cannot create the new processn); return 1; else if(pid=0) In the child process!n elseIn the parent process!运行结果:rootBC test# ./jc_fork调用fork函数后,其后代码会被父子进程分别执行。 fork();Will be executed twicenrootBC test# ./jc_fork2Will be executed twice三、vfork函数int g_var=0; int var=1;process id:%dn,(long)getpid();bef
2、ore execute the fork system call,g_var=%d var=%dn,g_var,var); printf(Cannot create a new process return 1; g_var+; var+;process id1:%d,g_var=%d var=%dn,(long)getpid(),g_var,var); _exit(0);process id2:rootBC test# ./fork_jc2597before execute the fork system call,g_var=0 var=12598,g_var=1 var=22597,g_
3、var=0 var=1由上可知,程序在子进程创建那一刻开始,父进程与子进程分别独立在不同的内存地址空间运行,且子进程复制了父进程的数据,从此数据分开处理。修改上面程序,将fork函数的语句进行替换,使用vfork函数,将代码保存并运行 if(pid=vfork()rootBC test# ./fork_jc226612662,g_var=1 var=22661,g_var=1 var=2由上可知,程序在子进程创建后,子进程直接在父进程的空间中运行,父进程挂起,直到子进程退出,父进程才再度调用,父进程的数据结构或栈会被子进程改变,g_var与var变为子进程最终的g_var与var。四、exec
4、函数族execvp函数支持参数列表,使用参数列表将使程序获得更大的灵活性,程序通过读取agrv中的参数,实现对输入的shell命令的执行。int main(int argc,char *argv) if(argcvoid do_at_exit(void)You can see the output when the progrom terminatesnint main() int flag; flag=atexit(do_at_exit); if(flag!=0)Cannot set exit functionn return EXIT_FAILURE; exit(EXIT_SUCCESS)
5、;OK /*检验exit()直接调用atexit注册函数退出*/rootBC test# ./exitYou can see the output when the progrom terminates由上面程序可知, atexit注册函数成功返回值为0,所以flag的值为0,exit()直接调用atexit注册函数退出_exit函数下面的程序和上面的除了推出函数不同,其他都一样。不同的是使用_exit函数退出时,不会执行atexit中注册的处理函数。 return EXIT_FAILURE; _exit(EXIT_SUCCESS);rootBC test# ./_exitrootBC tes
6、t#执行_exit函数与eint函数,内核都会将打开的文件关闭,将使用的内存地址空间释放,但前者不同是不处理打开的流缓冲区。(六)、kill 函数发送信号直接用kill函数给进程发送结束信号或是让进程自动退出。int main(int argc,char*argv) int h; /*定义一个变量,便于观察if语句的判断*/ int exit_code; pid=getpid();,pid); srand(unsigned)pid); exit_code=(int)(rand()%256); /*exit_code的十六进制值不超过ff*/ sleep(1); h=atoi(*(argv+1)
7、%2; /*atio()把字符转换为整型,h的值为0或1*/%dn ,h); if(h) /*h=1时,执行语句*/the child process id:%d recive signal SIGKILLn kill(pid,9);%d normally exit_code is %0xn,pid,exit_code); exit(exit_code);rootBC test# ./kill 42536 the child process id:2536 normally exit_code is 25rootBC test# ./kill 5253712537 recive signal
8、SIGKILLKilledrootBC test# ./kill a25482548 normally exit_code is c1由上可知,程序输入的第二参数argv1,为偶数和字母时,程序调用exit正常退出,为奇数时,程序调用kill自杀退出。下面程序通过fork函数创建子程序,并调用execl函数执行上面的程序。为方便了解程序运行的情况,在父进程中显示了创建的子进程的进程号。在while循环中调用wait函数,跳出条件是wait函数放回值小于0,或wait_pid为-1。这种情况下,所有的子进程都已经完全退出。sys/wait.h pid_t pid,wait_pid; int st
9、atus; int i;4)%s para1 para2 para3n for(i=1;i0,等待子进程结束 if(wait_pid=-1) perror(cannot using waitpid functionn exit(1); if(WIFEXITED(status) /子进程正常终止,则返回真 printf(child process exites,status=%dn,WEXITSTATUS(status); if(WIFSIGNALED(status) /子进程由信号终止,则返回真child process is killed by signal %dn,WTERMSIG(sta
10、tus); if(WIFSTOPPED(status) /信号导致子进程停止,则返回真child process is stopped by signal %dn,WSTOPSIG(status); / if(WIFCONTINUED(status) /信号导致子进程继续执行,则返回真 / printf(child process resume running.n while(!WIFEXITED(status)&!WIFSIGNALED(status); /信号或正常终止,/则跳出循环 exit(0); rootBC test# ./waitpid2496child process is k
11、illed by signal 14(1)、如果去掉第十九行与二十行代码/alarm(1);/pause();2674pausechild process exites,status=0此程序可使父进程周期性地检查某个特定的子进程是否已终止八、僵尸进程 if(pid sleep(60); perror(wake up! / 检查子进程的运行状况 exit(0);rootBC test# ./8_jc: Success注释:“wake up!”是子进程输出的,子进程输出并退出后,父进程还没退出,此时子进程就成为僵尸进程了。子进程终止时,它与父进程之间的关联会保持到父进程正常终止或父进程调用wait才结束。子进程成为僵尸进程情况:A、子进程先于父进程终止,子进程终止后,进程表中代表子进程的表项不会立刻释放,仍存在于系统中,保存以备父进程wait调用使用,于是子进程就成为死进程或僵尸进程。B、如果父进程先终止,子进程将自动把PID为1的进程,即init,作为父进程,此时子进程是个不再运行的僵尸进程,由init接管,保存在进程表中,直到init进程发现并释放。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1