• Linux下进程代码调试与理解


    Linux下进程代码调试与理解

    创建进程代码1:

    #include <stdio.h>
    void main( ) {
    	int p1,p2;
    	while((p1=fork())==-1);        /*创建子进程p1*/
    	if (p1==0)  putchar('b');
    	else {
    		while((p2=fork())==-1);   /*创建子进程p2*/
    		if(p2==0)  putchar('c');
    		else  putchar('a');
    	}
    }
    

    调试结果:

    1587797903776

    分析:这里的if和else不是以前理解的选择分支。fork后产生的子进程和父进程并行运行的.这种理解是不正确的。if 和 else 还是选择分支。 主要的原因是,fork() 函数调用一次,返回两次。两次返回的区别是:子进程的返回值是0,父进程返回值为新子进程的进程ID,至于abc顺序为什么先后,偶也是懵的,只知道是随机的。

    创建进程代码2:

    #include <stdio.h>
    void main( ) {
    	int p1,p2,i;
    	while((p1=fork())== -1);          /*创建子进程p1*/
    	if (p1==0)
    		for(i=0; i<10; i++)
    			printf("daughter  %d
    ",i);
    	else {
    		while((p2=fork())== -1);   /*创建子进程p2*/
    		if(p2==0)
    			for(i=0; i<10; i++)
    				printf("son  %d
    ",i);
    		else
    			for(i=0; i<10; i++)
    				printf("parent  %d
    ",i);
    	}
    }
    

    调试结果:

    1587798181254

    创建进程代码3(在2上加上sleep):

    #include <stdio.h>
    void main( ) {
    	int p1,p2,i;
    	while((p1=fork())== -1);          /*创建子进程p1*/
    	if (p1==0)
    		for(i=0; i<10; i++) {
    			printf("daughter  %d
    ",i);
    			sleep(1);
    		}
    
    	else {
    		while((p2=fork())== -1);   /*创建子进程p2*/
    		if(p2==0)
    			for(i=0; i<10; i++) {
    				printf("son  %d
    ",i);
    				sleep(1);
    			}
    
    		else
    			for(i=0; i<10; i++) {
    				printf("parent  %d
    ",i);
    				sleep(1);
    			}
    
    	}
    }
    

    调试结果:

    1587798393483

    创建进程代码4(在1上加上i观察结果):

    #include <stdio.h>
    void main( ) {
    	int p1,p2;
    	int i;
    	while((p1=fork())==-1);        /*创建子进程p1*/
    	if (p1==0)  putchar('b');
    	else {
    		while((p2=fork())==-1);   /*创建子进程p2*/
    		if(p2==0)  putchar('c');
    		else  putchar('a');
    	}
    	i++;
    	printf("i=%d
    ",i);
    }
    

    调试结果:

    1587798569866

    可以观察得出不同进程的i的值不同。

    管理进程代码:

    #include<stdio.h>
    #include <stdlib.h>
    #include<unistd.h>
    void main( )
    {      
            int pid;    
            pid=fork( );         /*创建子进程*/
    switch(pid) 
    {
                   case  -1:                          /*创建失败*/
                           printf("fork fail!
    ");
                           exit(1);
                   case  0:                                 /*子进程*/
                           execl("/bin/ls","ls","-1","-color",NULL);  
                           printf("exec fail!
    ");
                           exit(1);
                   default:                                 /*父进程*/
                           wait(NULL);                  /*同步*/
                           printf("ls completed !
    ");
                           exit(0);
              }
    }
    
    调试结果:

    1587799195418

    如果缺少wait:

    1587799377059

    分析:少了个wait就会先是父进程执行completed后,子进程才把ls打印出来

    如果目录写错:

    1587799424111

    分析:父进程未出现错误仍正常运行,子进程报错。

    互斥程序代码(加锁):

    #include <stdio.h>
    #include <unistd.h>
    void main() {
    	int p1,p2,i;
    	while((p1=fork( ))== -1);       /*创建子进程p1*/
    	if (p1==0) {
    		lockf(1,1,0);          /*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/
    		for(i=0; i<10; i++)
    			printf("daughter %d
    ",i);
    		lockf(1,0,0);                     /*解锁*/
    	} else {
    		while((p2=fork( ))==-1);  /*创建子进程p2*/
    		if (p2==0) {
    			lockf(1,1,0);        /*加锁*/
    			for(i=0; i<10; i++)
    				printf("son %d
    ",i);
    			lockf(1,0,0);            /*解锁*/
    		} else {
    			lockf(1,1,0);         /*加锁*/
    			for(i=0; i<10; i++)
    				printf(" parent %d
    ",i);
    			lockf(1,0,0);         /*解锁*/
    		}
    	}
    }
    

    互斥程序调试结果:

    1587799743277

    分析:lockf(1,1,0)是锁定屏幕输出,不让其他进程可以输出到屏幕,lockf(1,0,0)则是解锁,所以拿到锁的那个进程能够在屏幕上一直输出。

    互斥程序代码(未加锁):

    #include <stdio.h>
    #include <unistd.h>
    void main() {
    	int p1,p2,i;
    	while((p1=fork( ))== -1);       /*创建子进程p1*/
    	if (p1==0) {
    		//lockf(1,1,0);          /*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/
    		for(i=0; i<10; i++)
    			printf("daughter %d
    ",i);
    		//lockf(1,0,0);                     /*解锁*/
    	} else {
    		while((p2=fork( ))==-1);  /*创建子进程p2*/
    		if (p2==0) {
    			//lockf(1,1,0);        /*加锁*/
    			for(i=0; i<10; i++)
    				printf("son %d
    ",i);
    			//lockf(1,0,0);            /*解锁*/
    		} else {
    			//lockf(1,1,0);         /*加锁*/
    			for(i=0; i<10; i++)
    				printf(" parent %d
    ",i);
    			//lockf(1,0,0);         /*解锁*/c
    		}
    	}
    }
    

    运行结果:

    1587801839632

    分析:没有锁,他们是同步运行,顺序不分先后。

    互斥程序代码(加锁+sleep):

    #include <stdio.h>
    #include <unistd.h>
    void main() {
    	int p1,p2,i;
    	while((p1=fork( ))== -1);       /*创建子进程p1*/
    	if (p1==0) {
    		lockf(1,1,0);          /*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/
    		for(i=0; i<10; i++){
    			printf("daughter %d
    ",i);
    			sleep(1);
    		}
    			
    		lockf(1,0,0);                     /*解锁*/
    	} else {
    		while((p2=fork( ))==-1);  /*创建子进程p2*/
    		if (p2==0) {
    			lockf(1,1,0);        /*加锁*/
    			for(i=0; i<10; i++){
    				printf("son %d
    ",i);
    				sleep(1);
    			}
    				
    			lockf(1,0,0);            /*解锁*/
    		} else {
    			lockf(1,1,0);         /*加锁*/
    			for(i=0; i<10; i++){
    				printf(" parent %d
    ",i);
    				sleep(1);
    			}
    				printf(" parent %d
    ",i);
    			lockf(1,0,0);         /*解锁*/
    		}
    	}
    }
    

    运行结果:

    1587802099447

    分析:加上sleep也是一样的,他们是同步运行的。

  • 相关阅读:
    mysql子查询不支持limit问题解决
    mysql在把子查询结果作为删除表中数据的条件,mysql不允许在子查询的同时删除原表数据
    mysql多表删除指定记录
    px、em、rem、%、vw、vh、vm这些单位的区别
    golang 使用 gRPC
    golang 实现定时任务 cron
    golang 配置文件解析神器--viper
    GO语言异常处理机制
    分析源码理解GO语言文件操作
    用python刷算法--堆排序算法
  • 原文地址:https://www.cnblogs.com/lightice/p/12774651.html
Copyright © 2020-2023  润新知