• 【操作系统】7/35进程原语2


    读时共享写时复制

    单进程模式,一个父进程,父子进程映射就可以了,不需要共享。

    不需要拷贝可以。可以直接用。

    如果对子进程进行修改,一定是会断掉映射的。

    修改了,就进行拷贝。

    如果父进程修改了呢?

    父进程修改时,要维护子进程的修改副本,因此,父进程修改的时候,也出发写拷贝。

    否则会出现,父进程一直随着子进程在变化。很不好的情况。要及时备份,保证稳定性。

    例如之前的代码,如果没有写时复制,那么每个子进程的i都是不变的。


    waitpid

    进程回收函数。

    pid_t pid = waitpid(pid_t pid, int* status, int opt)

    回收僵尸进程,支持非阻塞回收方案。

    pid参数:

    1. 小于-1:指的是组,加负号就是组id,回收特定组里的id。跨组。
    2. 等于-1:回收任意子进程。任意。
    3. 等于0:同组回收,回收调用的进程。同组。
    4. 大于0:特定。

    opt参数:opt=WNOHANG(非阻塞)

    返回值:

    1. 大于0:成功了,返回的是僵尸进程的pid。
    2. 等于0:非阻塞,子进程无需回收。
    3. 等于-1:回收失败。

    非阻塞,可以干点别的,可以让父进程交替工作。

    阻塞,就得一直等着。

    非阻塞的waitpid函数,使得更加灵活。

    非阻塞轮询回收。

    1. int main(void){
    2. pid_t pid;
    3. pid_t zpid;
    4. int i=0;
    5. for(i;i<5;++i){
    6. pid=fork();
    7. if(!pid)break;
    8. }
    9. if(pid>0){
    10. printf("im father, and my pid is %d\n",getpid());
    11. while((zpid=waitpid(-1,NULL,WNOHANG))!=-1){
    12. if(zpid>0){
    13. printf("parent wait zombie success...\n");
    14. }else{
    15. printf("parent running...\n");
    16. sleep(1);
    17. }
    18. }
    19. }else if(!pid){
    20. printf("im child NO %d, and my pid is %d\n",i,getpid());
    21. sleep(i);
    22. exit(i);
    23. }else{
    24. perror("fork call failed\n");
    25. exit(1);
    26. }
    27. return 0;
    28. }

    其中,在父进程当中,必须把zpid赋值的过程写进循环里。

    因为每次都要进行一个赋值,然后判断,否则就死循环了。

    输出结果:

    LinuxDemo01

    关于进程校验。

  • 相关阅读:
    TypeScript & React(下)
    endnote设置
    CSAPP 之 DataLab 详解
    SpringBoot 3.2.5 引入Swagger(OpenApi)
    docker-compose安装ES7.14和Kibana7.14(有账号密码)
    VS_QT_5_Qt信号和槽
    局域网攻击与网络设备安全配置
    二维码的秘密(生成原理)
    【数据结构与算法】链表
    2022年8月22日,ue4热更新视频教程
  • 原文地址:https://blog.csdn.net/callmejielun/article/details/126249891