linux历程--进程控制编程

1)获取ID
      #include<sys/types.h>
      #include<unistd.h>
      //获取本进程ID
      pid_t getpid(void)
      //获取父进程ID
      pid_t getppid(void)

2)进程创建-fork
      #include<unistd.h>
      pid_t fork(void)
   功能:创建子进程。fork神奇地被调用一次,却返回两次(父进程当中返回一次,子进程当中返回一次),fork()之后的代码在两个进程中同时运行。它可能有三种不同返回值:
     <1> 在父进程中,fork返回新创建的子进程PID;
     <2> 在子进程中,fork返回0;
     <3> 如果出现错误,fork返回一个负值。
   例:fork.c
      #include<sys/types.h>
      #include<unistd.h>
      void main(void) {
          pid_t pid;
          /* 此时仅有一个进程 */
          pid = fork();
          /* 此时已经有两个进程同时运行,以下代码getpid()会获取不同的pid */
          if (pid < 0)  
              //父进程中运行
              printf("error in fork");  
          else if (pid == 0)
              //子进程中运行
              printf("I am the chlid process, ID is %d\n", getpid());
          else 
              //父进程中运行
              printf("I am the parent process, ID is %d\n", getpid());
       }
   总结:在pid=fork()之前,只有一个进程在执行,但在这条语句执行之后,就变成两个进程在执行了,这两个进程的共享代码段,将要执行的下一条语句都是if(pid==0)。两个进程中,原来存在的那个进程被称为“父进程”,新出现的那个进程被称作“子进程”,父子进程的区别在于进程标识符(PID)不同。
注意:fork()之后,父子进程的代码段共享,但数据段不共享,在fork的时候子进程会copy父进程的数据段,创建自己的独立数据段,如下程序:
  #include<unistd.h>
  #include<stdio.h>
  int main(void) {
     pid t_pid;
     int count = 0;
     
     pid = fork();
   
     count ++;
     printf("count = %d\n", count);

     return 0;
  }
  最终会打印两条count = 1。因为在fork以后子进程copy了父进程的代码段,拥有了自己的count变量,count++运算父子进程的count数据互不影响。

3)进程创建-vfork
     #include<sys/types.h>
     #include<unistd.h>
     pid_t vfork(void)
     功能:创建子进程
  fork与vfork的区别:
     fork:子进程拷贝父进程数据段
     vfork:子进程与父进程共享数据段
     fork:父子进程的执行次序不确定
     vfork:子进程先运行,父进程后运行

4)exec函数族
    exec用被执行的程序替换调用它的程序。仅仅替换程序代码,不替换进程。
   区别:
     fork创建一个新的进程,产生一个新的PID。
     exec启动一个新程序,替换原有的进程,因此进程的PID不变。
   
   #include<unistd.h>
   int execl(const char *path, const char *arg1, ...)
   参数: 
       path: 被执行程序名(含完整路径)。
       arg1~argn:被执行程序所需的命令行参数,含程序名,以空指针(NULL)结束。
   例:
       #include<unistd.h>
       void main() {
           execl("/bin/ls","ls","-l","/dev", (char *)0);

       }

  注意:不能直接execl("/bin/ls", "ls  -l  /dev ", (char *)0);


   #include<unistd.h>
   int execlp(const char *path, const char *arg1, ...)
   参数:  
       path:被执行程序名(不包含路径,将从path环境变量中查找该程序)。
       arg1~argn:被执行程序所需的命令行参数,含程序名,以NULL结束。
   例:
       #include<unistd.h>
       void main() {
           execlp("ls","ls","-l","/dev", (char *)0);
       }

   #include<unistd.h>
   int execv(const char *path, char *const argv[ ])
   参数:
       path:被执行程序名(含完整路径)
       argv[ ]:被执行程序所需命令行参数数组。
   例:
       #include<unistd.h>
       void main() {
           char *argv[] = {"ls", "-l", "/dev", (char *)0};
           execv("/bin/ls",argv);
       }

   #include<stdlib.h>
      int system(const char *string)
   功能:调用fork产生子进程,由子进程来调用 /bin/sh -c string 来执行参数string所代表的命令。
   例:
       #include<stdlib.h>
       void main() {
           system("ls  -l  /dev");  
       }

5)进程等待
   #include<sys/types.h>
   #include<sys/wait.h>
       pid_t wait(int *status)
   功能:阻塞该进程,直到他的某个子进程退出,该进程会由阻塞态变为就绪态而非运行态,是否会马上进入运行态要看其优先级是否最高而定。
   例:
      #include<sys/types.h>
      #include<sys/wait.h>
      #include<unistd.h>
      #include<stdlib.h>
      void main() {
          pid_t pc, pr;
          pc = fork();
          if (pc==0) { //如果是子进程
              printf("This is child process with pid of %d\n", getpid());
              sleep(10);   //睡眠10秒钟
          } else id (pc>0) { //如果是父进程
              pr = wait(NULL);   //等待
              printf("I catched a child process with pid of %d\n", pr);
          }
          exit(0);  //进程退出
      }

你可能感兴趣的:(linux历程--进程控制编程)