第12课-多进程程序设计

1. 创建进程

(1) 函数名

fork

(2) 函数原形

pid_t fork(void)

(3) 函数功能

创建一个子进程

(4) 所属头文件

#include<unistd.h>

(5) 返回值

成功:在父进程中返回子进程的pid,在子进程中返回的是0.

失败:-1

(6) 参数说明

无参数

(7) 范例程序

#include<unistd.h>

void main()

{

fork();

printf("program is end\n");

exit(0);

}

当我们运行这段程序的时候,我们发现program is end被打印了两次,下面我们来分析一下原因:

我们把上面的程序可以看成是父进程,当父进程运行到fork()函数的时候。会出现一个子进程,子进程的代码与父进程的一样。但是子进程并不是从代码的开头去运行,而是从fork()函数后面的代码开始运行。于是printf()函数一共被调用了两次。我们现在将程序做如下的修改:

#include<unistd.h>

void main()

{

pid_t pid;

pid = fork();

printf("pid is %d\n",pid);

exit(0);

}

程序被打印了两次,一次打印的是父进程的pid(是个数),一次打印的是子进程的pid(是0)。

这里面也出现了一个问题。那就是,既然父程序和子程序代码是一样的,我们怎么能让一样的代码去执行不一样的程序呢。实际我们只需要一个if语句就行,程序如下:

#include<unistd.h>

void main()

{

pid_t pid;

pid = fork();

if(pid>0)

{

printf("father process!\n");//操作1

exit(0);

}

else

{

printf("son process!\n");     //操作2

exit(0);

}

}

打印的结果是:father process!

son process!

2. 创建进程2

(1) 函数名

vfork

(2)函数原形

pid_t vfork(void)

(3)函数功能

创建一个子进程并且阻塞父进程

(4)所属头文件

#include<sys/types.h>

#include<unistd.h>

(5)返回值

成功:在父进程中返回子进程的pid,在子进程中返回的是0.

失败:-1

(6)参数说明

无参数

(7)范例程序

#include<unistd.h>

void main()

{

pid_t pid;

pid = vfork();

if(pid>0)

{

printf("father process!\n");//操作1

exit(0);

}

else

{

printf("son process!\n");     //操作2

exit(0);

}

}

打印的结果是:son process!

father process!

我们发现这里的程序和fork()的程序是一样的,但是产生的结果却是相反的。下面我们来分析一下:当我们创建了一个子进程后,到底是父进程还是子进程先运行呢?;而vfork()的作用是让子进程先运行;fork(()函数的作用不一定让那个程序先运行。

下面我们来分析一下fork()函数和vfork()函数的区别:

(1)父进程和子进程运行的顺序不同。

(2)我们来看一下下面两组程序的运行结果

#include<unistd.h>

#include<sys/types.h>

void main()

{

pid_t pid;

int count = 0;

pid = fork();

count++;

printf("count = %d\n",count);

exit(0);

}

运行结果:count = 1;

count = 1;

#include<unistd.h>

#include<sys/types.h>

void main()

{

pid_t pid;

int count = 0;

pid = vfork();

count++;

printf("count = %d\n",count);

exit(0);

}

运行结果:count = 1;

count = 2;

分析:count是存放在栈中的,当我们执行fork()时,我们将父进程中的栈也复制过来了,也就是子进程拥有自己独立的数据段和堆栈;在我们使用vfork()的时候,子进程是和父进程共享数据段和堆栈的。

3. 进程退出

我们在父进程中退出,可以使用return 0,也可以使用exit(),(exit(0)表示正常退出,exit(1)表示非正常退出);在子进程中我们只能使用exit()进行退出。

(1) 函数名

exit()

(2) 函数原形

exit()

(3) 函数功能

退出进程

(4) 所属头文件

#include<unistd.h>

(5) 返回值

(6) 参数说明

4. 进程等待

(1) 函数名

wait

(2) 函数原形

pid_t wait(int *status);

(3) 函数功能

挂起调用它的进程,直到其子进程结束。

(4) 所属头文件

#include<sys/types.h>

#include<ysy/wait.h>

(5) 返回值

成功:返回终止的那个子进程的id

失败:-1

(6)参数说明

status:记录子进程的退出状态

(7)范例程序

#include<unistd.h>

#include<sys/types.h>

#include<sys/wait.h>

void main()

{

pid_t pid;

pid = fork();

if(pid>0)

{

wait(NULL);

printf("father process!\n");//操作1

exit(0);

}

else

{

printf("child process!\n");     //操作2

exit(0);

}

}

结果显示:chlid process!

father process!

分析:在运行到父进程的时候进入wait(NULL)函数,直到子进程运行结束再运行父进程。

5. 执行程序

执行程序是一个exec族,其中包含:execl,execv,execle,execve,execlp,execvp。我们现在只对其中一个做介绍,因为它们的功能都是差不多的。我们可以自学system这个函数,它的功能和exec类似。

(1) 函数名

execl

(2) 函数原形

int execl(const char *pathname,const char *arg,...);

(3) 函数功能

运行可执行文件

(4) 所属头文件

#include<unistd.h>

(5) 返回值

成功:不返回

失败:有返回

(6) 参数说明

pathname:要运行的可执行文件的路径

arg(包括后面的参数):可执行文件运行需要的参数。

(7) 范例程序

#include<unistd.h>

#include<sys/types.h>

#include<sys/wait.h>

void main()

{

pid_t pid;

pid = fork();

if(pid>0)

{

wait(NULL);

printf("father process!\n");//操作1

exit(0);

}

else

{

execl("/bin/ls","ls","/home",NULL);

printf("child process!\n");     //操作2

exit(0);

}

}

运行结果:free test.txt work

father process!

在子进程中的运行结果和我们直接运行ls命令是一样的。但是子进程中的打印程序没有被显示出来。原因是,当我们运行execl()命令时,我们会保留原有的进程,它后面的内容会被覆盖。这也是它和fork()函数的区别。

转载于:https://www.cnblogs.com/free-1122/p/11345610.html

第三季-第12课-多进程程序设计相关推荐

  1. Python可以这样学(第三季:多线程与多进程编程)-董付国-专题视频课程

    Python可以这样学(第三季:多线程与多进程编程)-7527人已学习 课程介绍         董付国老师系列教材<Python程序设计(第2版)>(ISBN:9787302436515 ...

  2. 20172319 2018.10.12《Java程序设计教程》第6周课堂实践(补写博客)

    20172319 2018.10.12 <Java程序设计教程>第6周课堂测验 课程:<程序设计与数据结构> 班级:1723 学生:唐才铭 学号:20172319 指导老师:王 ...

  3. 第12课第3节 字符设备驱动程序之查询方式的按键驱动程序

    第12课第3节 字符设备驱动程序之查询方式的按键驱动程序 cat /proc/devices //查询主设备号 insmod ./second_drv.ko ls /dev/button -l pos ...

  4. 第12课第2.2节 字符设备驱动程序之LED驱动程序_测试改进

    第12课第2.2节 字符设备驱动程序之LED驱动程序_测试改进 //仅用flash上的根文件系统启动后,手工MOUNT NFS mount -t nfs -o nolock,vers=2 192.16 ...

  5. java程序设计_十分钟说课—Java程序设计(耿祥义)

    "十分钟说课"-Java程序设计 耿祥义视频说课: 课程概述 1. Java入门 1) 重点内容,三个基本步骤: 编写源文件,编译,运行. 2)JDK,使用JDK11以上版本,注意 ...

  6. 读取usb口数据_Mixly 第12课 模拟值读取实验串口使用

    第12课  模拟值读取实验--串口使用 串行通信是在实现在PC机与微控制器进行交互的最简单的办法.以常见的Arduino UNO为例,面板上只有一组串行端口,即引脚 0(RX)和1(TX).电脑与Ar ...

  7. 数据结构个人笔记 第12课 数组

    数据结构个人笔记 第12课 数组 数组 数组的顺序存储 多维数组查找指定元素 示范代码 矩阵(稀疏矩阵)压缩存储(三种方式) 对称矩阵 上(下)三角矩阵 稀疏矩阵 数组 一说起数组,我们的印象中数组往 ...

  8. 第12课 Altium Designer20(AD20)+VESC6.4实战教程:原理图最后验证(北冥有鱼)

    第12课 Altium Designer20(AD20)+VESC6.4实战教程:原理图最后验证(北冥有鱼)

  9. 软件工程课设程序设计

    软件工程课设程序设计 1.系统设计 系统可分为5个子系统:书籍信息录入系统.读者信息录入系统.借阅情况录入系统.计算扣款金额系统.人员及图书信息查询系统 书籍信息录入系统:图书管理员录入书籍的书号.名 ...

  10. 五年级下册计算机课ppt课件ppt课件,小学信息技术浙摄影版五年级下册第12课 制作演示文稿课堂教学ppt课件...

    这是一份小学信息技术浙摄影版五年级下册第12课 制作演示文稿课堂教学ppt课件,文件包含第12课制作演示文稿课件pptx.第12课制作演示文稿教学设计doc等2份课件配套教学资源,其中PPT共8页, ...

最新文章

  1. golang通过itemid获取zabbix graph监控图
  2. 两个高频设计类面试题:如何设计HashMap和线程池
  3. map集合遍历_集合框架的部分内容
  4. select选择框变得可以输入、编辑
  5. PHP内存管理 垃圾回收
  6. sqlite和java_Java和SQLite
  7. 掏出来的“耳屎经济”
  8. python 运维包_python运维常用模块
  9. PAT (Basic Level) Practise (中文)-1034. 有理数四则运算(20)
  10. linux运行非法指令,illegal instruction非法指令的解决思路
  11. Qt qlabel 设置字体、大小、加粗等
  12. c语言程序答设计答案张文祥,c语言程序设计答案张文祥
  13. 【分享实录-猫眼电影】业务纵横捭阖背后的技术拆分与融合
  14. 【Python 实战基础】Pandas如何统筛选复制某个数据
  15. 干货全拿走-用Excel制作小市值轮动价值投资选股器
  16. Google VR开发-Cardboard VR SDK头部追踪实现(罗德里格旋转公式)
  17. python提取cad坐标_怎么提取cad中坐标?CAD批量提取坐标点的三种方法
  18. 【linux C】基础
  19. word 以嵌入式插入图片显示不全,被文字掩盖在下方
  20. 控件:TextView

热门文章

  1. Flutter之Redux框架入门
  2. 5双机配置_SBC双机热备解决方案
  3. 卡方分布分位数_数理统计第五讲(三大分布)
  4. 华为慧通和华为区别_华为P30与华为P30 pro 的区别
  5. Python 爬取电影街美剧网址
  6. mysql 数据字典详解_MySQL8功能详解——数据字典
  7. 学生选课系统代码-5-共用代码层
  8. 计算机辅助设计与制造考试重点,计算机辅助设计与制造复习内容
  9. linux安装python的拓展包,linux 安装python拓展包pexpect
  10. 使用 Docker Machine 添加机器记录