一: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. printf("exiting main process -----\n");
  10. return 0;
  11. }

程序的执行结果就是我/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) |

给主人留下些什么吧!~~
评论热议

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

fork()和vfork()的区别,signal函数用法,exec()系列函数的用法小结的更多相关文章

  1. fork()和vfork()的区别(转载)

    fork和vfork 转载 http://coolshell.cn/articles/12103.html 在知乎上,有个人问了这样的一个问题--为什么vfork的子进程里用return,整个程序会挂 ...

  2. exec系列函数(execl,execlp,execle,execv,execvp)使用

    本节目标: exec替换进程映像 exec关联函数组(execl.execlp.execle.execv.execvp) 一,exec替换进程映像 在进程的创建上Unix采用了一个独特的方法,它将进程 ...

  3. linux系统编程之进程(五):exec系列函数(execl,execlp,execle,execv,execvp)使用

    本节目标: exec替换进程映像 exec关联函数组(execl.execlp.execle.execv.execvp) 一,exec替换进程映像 在进程的创建上Unix采用了一个独特的方法,它将进程 ...

  4. exec系列函数和system函数

    一.exec替换进程映象 在进程的创建上Unix采用了一个独特的方法,它将进程创建与加载一个新进程映象分离.这样的好处是有更多的余地对两种操作进行管理.当我们创建 了一个进程之后,通常将子进程替换成新 ...

  5. fork和vfork的区别

    参见百度百科API说明: fork 头文件: #include<unistd.h> #include<sys/types.h> 函数原型: pid_t fork( void); ...

  6. Linux系统编程(9)—— 进程之进程控制函数exec系列函数

    在Linux中,并不存在exec()函数,exec指的是一组函数,一共有6个,分别是: #include <unistd.h> extern char **environ; int exe ...

  7. 进程基本-进程创建,僵尸进程,exec系列函数

    Linux系统中,进程的执行模式划分为用户模式和内核模式,当进程运行于用户空间时属于用户模式,如果在用户程序运行过程中出现系统调用或者发生中断事件,就要运行操作系统(即核心)程序,进程的运行模式就变为 ...

  8. exec系列函数详解

    execve替换进程映像(加载程序):execve系统调用,意味着代码段.数据段.堆栈段和PCB全部被替换.在UNIX中采用一种独特的方法,它将进程创建与加载一个新进程映像分离.这样的好处是有更多的余 ...

  9. PHP 使用 curl_* 系列函数和 curl_multi_* 系列函数进行多接口调用时的性能对比

    在页面中调用的服务较多时,使用并行方式,即使用 curl_multi_* 系列函数耗时要小于 curl_* 系列函数. 测试环境 操作系统:Windows x64 Server:Apache PHP: ...

随机推荐

  1. Centos8.X 搭建Prometheus+node_exporter+Grafana实时监控平台

    Prometheus Promtheus是一个时间序列数据库,其采集的数据会以文件的形式存储在本地中,因此项目目录下需要一个data目录,需要我们自己创建,下面会讲到 下载 下载好的.tar.gz包放 ...

  2. P6624-[省选联考2020A卷]作业题【矩阵树定理,欧拉反演】

    正题 题目链接:https://www.luogu.com.cn/problem/P6624 题目大意 \(n\)个点的一张图,每条边有权值,一棵生成树的权值是所有边权和乘上边权的\(gcd\),即 ...

  3. linux启动redis命令

    首先进入到/usr/local/bin目录下(因为你redis安装的目录绝大多数都在这里) root@xxxx:/usr/local/bin#:redis-server wangconfig/redi ...

  4. 题解 SP6779 【GSS7 - Can you answer these queries VII】

    题目传送门 题目大意 给出一个\(n\)个点的树,每个点有权值.有\(m\)次操作,每次要么查询一条链上的最大子段和,要么把一条链的权值都修改为一个常数. \(n,m\le 10^5\) 思路 如果是 ...

  5. 题解 [NOI2014]购票

    题目传送门 题目大意 有一个 \(n\) 个点的树,每个点有三个值 \(p_u,q_u,l_u\) ,现在可以从 \(u\) 走到点 \(v\) 当且仅当 \(v\) 是 \(u\) 的祖先并且 \( ...

  6. CF739E Gosha is hunting(费用流/凸优化dp)

    纪念合格考爆炸. 其实这个题之前就写过博客了,qwq但是不小心弄丢了,所以今天来补一下. 首先,一看到球的个数的限制,不难相当用网络流的流量来限制每个球使用的数量. 由于涉及到最大化期望,所以要使用最 ...

  7. 洛谷3721 HNOI2017单旋(LCT+set+思维)

    这题难道不是spaly裸题吗? 言归正传QWQ 一看到这个题目,其实第一反应是很懵X的 从来没有见过类似的题目啊,什么\(spaly\),单旋.QWQ很懵逼啊 不过,我们可以注意到这么一件事情,就是我 ...

  8. javascript-jquery对象的css处理

    一.css基本属性处理 1.css()方法:获取css属性值.$("选择器").css(name);//获取匹配选择器的元素指定css属性值. 2.css()方法:设置css属性值 ...

  9. F1西班牙大奖赛-加泰罗尼亚赛道地图及简介

    背景 银石双赛结束,第二轮三连赛的最后一场将转战西班牙,第50届F1西班牙大奖赛将于本周末(正赛2020-08-15)在加泰罗尼亚赛道上演. 作为近年来F1承办季前测试的赛道,所有人都对这里再熟悉不过 ...

  10. 【c++ Prime 学习笔记】第3章 字符串、向量和数组

    string和vector是两类最重要的标准库类型 strng表示可变长的字符序列 vector存放某种给定类型对象的可变长序列. 3.1 命名空间的using声明 using namespace:: ...