fork()和vfork()的区别,signal函数用法,exec()系列函数的用法小结

一:fork()和vfork()的区别:
   fork()函数可以创建子进程,有两个返回值,即调用一次返回两个值,一个是父进程调用fork()后的返回值,该返回值是刚刚创建的子进程的ID;另一个是子进程调用fork()后的返回值,该返回值为0。
   vfork与fork不同的地方在于:
   使用fork()创建子进程时:子进程只是完全复制父进程的资源,并且哪个进程先运行取决于系统的调度算法。

点击(此处)折叠或打开

  1. int globVar = 5;
  2.     int main(int argc,char *argv[])
  3.     {
  4.         int var = 1,i;
  5.         pid_t pid;

  6.         printf("fork is different with vfork\n");

  7.         pid = fork();
  8.  // pid = vfork();
  9.         printf("%d---------\n",pid);
  10.         switch(pid)
  11.         {
  12.             case 0:
  13.             i = 2;
  14.             while(i-- > 0)
  15.             {
  16.                 printf("--------Child process is running\n");
  17.                 globVar++;
  18.                 var++;
  19.                 printf("--------c sleep\n");
  20.                 sleep(1);
  21.             }
  22.             printf("--------Clild's globVar = %d,var = %d\n",globVar,var);
  23.             break;
  24.             case -1:
  25.                 perror("Process creat faild\n");
  26.                 exit(0);
  27.             default:
  28.                 i = 3;
  29.                 while(i-- > 0)
  30.                 {
  31.                 printf("Parent process is running\n");
  32.                 globVar++;
  33.                 var++;
  34.                 printf("p sleep\n");
  35.                 sleep(1);

  36.                 }
  37.                 printf("Parent's globVar = %d,var = %d\n",globVar,var);
  38.                 exit(0);
  39.         }
  40.     }



  41. fork is different with vfork
  42. 14070---------
  43. Parent process is running
  44. p sleep
  45. 0---------
  46. --------Child process is running
  47. --------c sleep
  48. Parent process is running
  49. p sleep
  50. --------Child process is running
  51. --------c sleep
  52. Parent process is running
  53. p sleep
  54. --------Clild's globVar = 7,var = 3
  55. Parent's globVar = 8,var = 4
     使用vfork()创建子进程时:操作系统并不将父进程的地址空间完全复制到子进程,子进程共享父进程的地址空间,并且保证子进程先运行。

点击(此处)折叠或打开

  1. 将上面的例子vfork()注释去掉,而将fork();注释掉,可以得到与之不同的结果

  2. fork is different with vfork
  3. 0---------
  4. --------Child process is running
  5. --------c sleep
  6. --------Child process is running
  7. --------c sleep
  8. --------Clild's globVar = 7,var = 3
  9. 14160---------
  10. Parent process is running
  11. p sleep
  12. Parent process is running
  13. p sleep
  14. Parent process is running
  15. p sleep
  16. Parent's globVar = 10,var = 32714
二:signal函数,可以用来处理我们系统的一些信号。

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler));
函数的第一个参数指定该信号的值,第二个参数指定对该信号的处理。可以忽略该信号。参数设为(SIG_ING),也可以采用系统默认的方式,参数设置为(SIG_DFL),下面的例子就是忽略我们的输入信号。

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<signal.h>
  3. int main(int argc ,char *argv[])
  4. {
  5.     signal(SIGINT,SIG_IGN);
  6.     for(;;);
  7.     return 0;
  8. }


执行结果就是无限循环,我们ctrl+c也无法停止。
三:exec系列函数(execl,execlp,execle,execv,execvp)函数用法总结:
   exec系列函数均可以把当前进程替换成一个新进程,保持原有的pid不变。对于以上函数,我按照自己的理解分为三类,当然这不一定是最好的方法,具体看自己了。
   1:execl和execlp:我们给它传入相应命令和参数,它就可以脱离当前进程而独立出来。他们两个的不同在于第一个参数传绝对路径还是相对路径,请看下面例子:

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<unistd.h>
  4. int main(int argc,char *argv[])
  5. {
  6.     printf("entering main process----\n");
  7. // execl("/bin/ls","ls","-l","/home",NULL);
  8. // execlp("ls","ls","-l","/home",NULL);
  9.     
  10.     printf("exiting main process -----\n");

  11.     return 0;
  12. }
程序的执行结果就是我/home中的内容了,而第10行的内容并不会被打印出来。有没有懂一点点呢,继续;
   2:execv和execvp函数:同样,后面有p就是它可以只传入文件名或者命令名就可以执行,不过它的参数可以自己用argv[]传进去。

点击(此处)折叠或打开

  1. int ret;

  2.     printf("entering main process----\n");
  3.     char *argv[] = {"ls","-l","/home",NULL};
  4.  // ret = execv("/bin/ls",argv);
  5.     ret = execvp("ls",argv);
  6.     if(ret == -1)
  7.     {
  8.         perror("execvp error");
  9.     }
  10.     printf("exiting main process-----\n");
  11.     return 0;
看吧,主要是execv和execvp只能传入两个参数,所以把其他的东西就放在argv[]中了,执行成功返回0,失败返回-1。
   3:execle函数,可以获得环境变量,看下面例子:
(注意:test_execle_child 是一个可以打印当前环境变量的函数)
test_execle_child函数如下:

点击(此处)折叠或打开

  1. extern char ** environ;

  2. int main(int argc,char *argv[])
  3. {
  4.     int i ;

  5.     printf("\n\n现在已经进入main函数中的子程序---- pid=%d\n",getpid());
  6.     sleep(2);
  7.     for(i = 0;environ[i] != NULL;i++)
  8.     {
  9.         printf("%s\n",environ[i]);
  10.     }
  11.     return 0;

  12. }

点击(此处)折叠或打开

  1. int ret;
  2.     char * const envp[] = {"aa=11","bb=22","cc=33",NULL};

  3.     printf("entering main process----\n");
  4.  // ret = execl("./test_execle_child","test_execle_child",NULL);
  5.     ret = execle("./test_execle_child","test_execle_child",NULL,envp);
  6.     if(ret == -1)
  7.     {
  8.         perror("execle error");
  9.     }
  10.     printf("exiting main process-----\n");
  11.     return 0;
当函数是execle时:输出我们envp中传进去的环境变量,
当函数时execl时:输出我们当前执行进程的环境变量。
阅读(1) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2015-08-04 21:07  杨博东的博客  阅读(303)  评论(0编辑  收藏  举报

导航