zoukankan      html  css  js  c++  java
  • linux之C编程学习——进程,进程,进程!

      linux支持多个进程同时进行,也就是我们常说的现代操作系统中的多道程序设计,所谓同时是linux系统调度各个进程分别占用cpu的时间。由于每个时间片的时间很小和宏观时间相比,给人的感觉是多个进程在运行。为了提高程序的运行效率,程序往往分成多个部分组成,这也就是说的并发程序设计。并发程序中各进程是相互独立的,在必要的时候会通过相应的机制进行通信。若进程间要共享资源,为了避免出现冲突,常通过相应通信机制使它们轮流使用共享资源。在进程进行通信时,会出现一个进程等另一个进程完,才能继续运行的情况,这也需要进程间通信以了解对方的运行情况。有时进程间会出现互斥现象,这是会用到锁机制。在并发程序设计中,进程的创建和结束是由用户决定的。这也就出现了父进程和子进程概念。

    进程的创建:

    1 #include <unistd.h>  
    2   
    3 pid_t fork(void);   
    4 pid_t vfork(void); 

      在这简述,fork创建的子进程是父进程的一个拷贝,但是和父进程使用不同的数据段和堆栈。vfork和fork基本相同但是vfork不会复制父进程的数据段,它们共享数据段。这是因为vfork常和exec函数使用去调用一个程序如ls命令,开启一个新的进程。vfork后父进程会等待子进程运行结束或调用了exit。fork后父进程和子进程的运行顺序是不确定的。

    下面是体现它们性质的程序:

     1 #include <sys/types.h>  
     2 #include <stdio.h>  
     3 #include <stdlib.h>  
     4 #include <unistd.h>  
     5    
     6 main()    
     7 {  
     8      pid_tpid;  
     9      char*pchar = "before fork";  
    10      inttest_va = 1;  
    11   
    12      if((pid= fork()) < 0 )  
    13      {  
    14          printf("forkerror!!
    ");  
    15          exit(1);  
    16      }  
    17   
    18      elseif(pid == 0)  
    19      {  
    20          printf("childprocess
    ");  
    21          pchar= "child pchr
    ";  
    22          printf("%s
    ",pchar);  
    23   
    24          test_va= 2;  
    25   
    26          printf("%d
    ",test_va);  
    27          _exit(2);  
    28      }  
    29   
    30      else  
    31      {  
    32          printf("parentprocess
    ");  
    33          printf("%s
    ",pchar);  
    34          printf("%d
    ",test_va);  
    35      }    
    36 } 

    fork:

    vfork:

    进程等待:

     1 #include <sys/types.h>  
     2 #include <stdio.h>  
     3 #include <sys/wait.h>  
     4   
     5 void check_exit(int status);  
     6   
     7 main()  
     8 {  
     9     pid_t pid;  
    10     int status;  
    11     if((pid = fork()) < 0)  
    12     {  
    13     printf("fork error!!
    ");  
    14     exit(0);  
    15     }  
    16     else if(pid == 0)  
    17     {  
    18     printf("child process exit
    ");  
    19     exit(0);  
    20     }  
    21     else  
    22     {  
    23         if(wait(&status) != pid)  
    24         {  
    25         printf("wait error!!");  
    26         exit(0);  
    27         }  
    28         check_exit(status);  
    29     }  
    30   
    31 }  
    32 void check_exit(int status)  
    33 {  
    34     if(WIFEXITED(status))  
    35         printf("eixt
    ");  
    36       
    37     else if(WIFSIGNALED(status))  
    38         printf("killed by signal
    ");  
    39     else if(WIFSTOPPED(status))  
    40         printf("stopped by signal
    ");  
    41     else if(WIFCONTINUED(status))  
    42         printf("continued");  
    43 }  

      等待进程改变其状态。所有下面哪些调用都被用于等待子进程状态的改 变,获取状态已改变的子进程信息。状态改变可被认为是:1.子进程已终止。2.信号导致子进程停止执行。3.信号恢复子进程的执行。在子进程终止的情况 下,wait调用将允许系统释放与子进程关联的资源。如果不执行wait,终止了的子进程会停留在"zombie"状态。如果发现子进程改变了状态,这些调用会立即返回。反之,调用会被阻塞直到子进程状态改变,或者由信号处理句柄所中断(假如系统调用没有通过sigaction的SA_RESTART标志重启动)。wait 系统调用挂起当前执行中的进程,直到它的一个子进程终止。waitpid挂起当前进程的执行,直到指定的子进程状态发生变化。默认,waitpid只等待 终止状态的子进程,但这种行为可通过选项来改变。waitid系统调用对于等待哪个子进程状态改变提供了更精确的控制。

      子进程已终止,父进程尚未对其执行wait操作,子进程会转入“僵死”状态。内核为“僵死”状态的进程保留最少的信息量(进程标识,终止状态,资源使用信息),过后 父进程执行wait时可以获取子进程信息。只要僵死的进程不通过wait从系统中移去,它将会占据内核进程表中的一个栏位。如果进程表被填满,内核将不能 再产生新进程。如果父进程已终止,它的僵死子进程将由init进程收养,并自动执行wait将它们移去。

    #include<sys/types.h>   
    #include<sys/wait.h>  
      
    pid_t wait (int * status); 

      wait()会暂时停止目前进程的执行(挂起父进程),直到有信号来到或子进程结束。如果在调用 wait()时子进程已经结束,则 wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一快返回。如果不在意结束状态值,则参数 status 可以设成 NULL。如果调用wait的进程没有子进程则会调用失败,子进程的结束状态值参考 waitpid( );如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno 中。

  • 相关阅读:
    蒙特卡洛采样、重要性采样
    伯努利分布和高斯分布下的最大似然估计、交叉熵
    对于分类问题的神经网络最后一层的函数:sigmoid、softmax与损失函数
    android 侧滑菜单
    安卓Animation类与xml制作动画
    LeetCode题解 #3 Longest Substring Without Repeating Characters
    GY89的使用
    使用GY89的BMP180模块获取温度和压强(海拔)
    STM32与PC机串口通讯
    STM32使用无源蜂鸣器演奏歌曲
  • 原文地址:https://www.cnblogs.com/geekpaul/p/4278936.html
Copyright © 2011-2022 走看看