Unix环境高级编程:第八章

进程控制
这一章的重点是fork,wait,waitpid,exec函数,接下来就根据demo来了解这几个函数,就不抄apue了,内容太多,重点不突出哈。。。
1:fork函数
pid_t fork(void)
对于fork函数,它一次调用,两次返回,由fork创建的进程是字进程,对于父进程,fork函数返回子进程的pid,对于子进程,fork函数返回0。子进程和父进程继续执行fork调用之后的指令,子进程此时是父进程的一个副本,子进程获得父进程数据空间、队、栈的副本。由于fork后子进程一般执行exec函数,所以现在很多实现并不执行父进程数据段、堆和栈的完全副本,使用了写时复制技术。对于父进程和子进程共享的区域,内核将他们的权限设为只读,如果发生了写操作,则会产生一个缺页中断,内核只为被修改的那一页做副本。

 1 #include "apue.h"
  2 
  3 int globvar = 6;
  4 char buf[] = "a write to stdout\n";
  5 
  6 int main()
  7 {
  8     int var;
  9     pid_t pid;
 10     var = 88;
 11     if(write(STDOUT_FILENO,buf,sizeof (buf) - 1) != sizeof(buf) - 1)
 12     {
 13         err_sys("write error");
 14     }
 15     printf("before fork\n");
 16 
 17     if((pid = fork()) < 0)
 18     {
 19         err_sys("fork error");
 20     }
 21     else if(pid == 0)
 22     {
 23         globvar++;
 24         var++;
 25     }
 26     else {
 27         sleep(2);
 28     }
 29     printf("pid = %ld,glob = %d,var = %d\n",(long)getpid(),globvar,var);
 30     exit(0);
 31 }

在这里插入图片描述上面的例子中,子进程更改了var的值,但是父进程的var不变。
当然,父进程和子进程虽然执行写时复制操作,但两者还有不同:
(1) fork(2) 的返回值不同;
(2) 父子进程的 PID 不相同;
(3) 父子进程的 PPID 不相同; // PPID 就是父进程 PID
(4) 在子进程中资源的利用量清零,否则如果父进程打开了很多资源,子进程能使用的资源量就很少了;
(5) 未决信号和文件锁不继承。

2:wait waitpid 函数
在父进程fork出子进程后,如果子进程在父进程结束前结束,那么父进程需要调用wait函数或者waitpid函数来回收子进程,否则子进程会编程僵尸进程,所谓僵尸进程就是进程虽然已经结束了,但是这个进程依旧占用某些资源。
在调用wait或者waitpid函数后,进程会有以下三种状态:
(1) 如果其所有的子进程都还在运行,则阻塞
(2) 如果一个子进程已经终止,正等待父进程获取其终止状态,则取得该子进程的终止状态并立即返回
(3)如果其没有任何子进程,则立即返回出错
wait和waitpid有以下区别
在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项可使其调用者不阻塞。
waitpid并不等待在调用之后的第一个终止子进程,他有若干个选项,可以控制它等待的进程。

#include "apue.h"
#include<sys/wait.h>

void pr_exit(int status)
{
    if(WIFEXITED(status))
        printf("normal termination,exit status = %d\n",WEXITSTATUS(status));
    else if(WIFSIGNALED(status))
        printf("abnormal termination,signal number = %d%s\n",
               WTERMSIG(status),
#ifdef WCOREDUMP
    WCOREDUMP(status) ? "(core file generated)" : "");
#else
    "");
#endif
    else if(WIFSTOPPED(status))
        printf("child stopped,signal number = %d\n",WSTOPSIG(status));
}

int main(void)
{
    pid_t pid;
    int status;
    if((pid = fork()) < 0)
        err_sys("fork error");
    else if(pid == 0)
        exit(7);
    if(wait(&status) != pid)
        err_sys("wait error");
    pr_exit(status);
    if((pid == fork()) < 0)
        err_sys("fork error");
    else if(pid == 0)
        abort();
    if(wait(&status) != pid)
        err_sys("wait error");
    pr_exit(status);
    if((pid = fork()) < 0)
        err_sys("fork error");
    else if(pid == 0)
        status /= 0;
    if(wait(&status) != pid)
        err_sys("wait error");
    pr_exit(status);
    exit(0);
}
1 #include "apue.h"
  2 #include<sys/wait.h>
  3 
  4 int main(void)
  5 {
  6     pid_t pid;
  7     if((pid = fork()) < 0)
  8     {
  9         err_sys("fork error");
 10     }
 11     else if(pid == 0)
 12     {
 13         if((pid = fork()) < 0)
 14         {
 15             err_sys("fork error");
 16         }
 17         else if(pid > 0)
 18           exit(0);
 19 
 20         sleep(2);
 21         printf("second child,parent pid = %ld\n",(long)getppid());
 22         exit(0);
 23     }
 24     else
 25     {
 26         if(waitpid(pid,NULL,0) != pid)
 27                err_sys("waitpid error");
 28         sleep(3);
 29     }
 30     exit(0);
 31 }

3:exec函数
当调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序从main函数处开始执行

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include "apue.h"
  5 
  6 int main()
  7 {
  8     pid_t pid;
  9     puts("Begin!");
 10     fflush(NULL);
 11     pid = fork();
 12     if(pid < 0)
 13     {
 14         perror("fork()\n");
 15     }
 16     else if(pid == 0)
 17     {
 18         execl("/home/weilon01/study/C++_Profile/apue/chapter8/8_4_demo","8_4_demo","./",NULL);
 19         perror("execl()");
 20         exit(1);
 21     }
 22     else
 23     {
 24         printf("father pid\n");
 25     }
 26     wait(NULL);
 27     puts("End!");
 28     exit(0);
 29 }

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值