weiqi7777

进击吧,linux(十三) 多进程编程

0
阅读(2375)

                                            

         Linux是一个可以执行多进程的操作系统,因此是可以在程序中,创建多进程。来完成不同的功能。多进程的编程,也是通过几个函数来学习的。

      4.1 创建进程

4.1.1 函数名

   fork

4.1.2 函数原形

   pid_t fork(void)

4.1.3 函数功能

   创建子进程

4.1.4 所属头文件

   <unistd.h>

4.1.5 返回值

   成功:父进程返回0 ,子进程返回pid

   失败:-1

4.1.6 参数说明

  

4.1.7 示例代码

   clip_image001

         使用fork创建子进程,通过判断pid,得知是父进程还是子进程运行,然后再执行自己的程序。

         使用fork创建的父进程,父子进程执行的顺序是不确定的。

4.2 创建进程

4.2.1 函数名

   vfork

4.2.2 函数原形

   pid_t vfork(void)

4.2.3 函数功能

   创建子进程,并阻塞父进程

4.2.4 所属头文件

   <sys/types.h> <unistd.h>

4.2.5 返回值

   成功:父进程返回子进程的pid ,子进程返回0

   失败:-1

4.2.6 参数说明

  

4.2.7 示例代码

   clip_image002

         使用vfork创建子进程,子进程执行一定在父进程前,因为创建子进程后,就将父进程给阻塞掉了。

4.3 进程等待

4.3.1 函数名

   wait

4.3.2 函数原形

   pid_t wait(int *status)

4.3.3 函数功能

   阻塞父进程,直到有一个子进程结束,父进程才执行

4.3.4 所属头文件

   <sys/types.h>      <sys/wait.h>

4.3.5 返回值

   成功:返回结束的子进程的pid

   失败:-1

4.3.6 参数说明

   status 子进程结束的状态保存

4.3.7 示例代码

   clip_image003

         使用wait后,父进程就被阻塞掉了,要等待一个子进程结束。这里只有一个子进程,等待5s子进程执行完毕后,父进程就可以执行了。

4.4 执行程序

4.4.1 函数名

   execl

4.4.2 函数原形

   Int execl(const char *path, const char *arg,….)

4.4.3 函数功能

   执行path指定的程序

4.4.4 所属头文件

   <unistd.h>

4.4.5 返回值

   成功:没有返回值

   失败:-1

4.4.6 参数说明

   path:程序名(带路径)

   arg 命令的参数

   。。。: 可选参数,看执行的命令需要的参数决定

4.4.7 示例代码

         clip_image005

         使用execl执行指定目录下的程序,就不会再返回了,所以就看不到打印children了。

         对于系统自带的函数,使用有点不一样,按以下使用。         

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

         对于使用forkvfork,创建出来的子进程执行的程序是父进程forkvfork后的程序。

clip_image007

         通过上面这个图,就可以知道子进程执行的代码是什么了。也就是父进程程序fork或者vfork之后的代码。

         forkvfork都可以创建子进程,但是也有一些不同:

1、  fork:子进程拥有独立的数据段,堆栈

vfork:子进程与父进程共享数据段,堆栈

2、  fork:父、子进程的执行次序不确定

vfork:子进程先运行,子进程运行结束后,才运行父进程

怎么理解第一个不同了,写一个代码测试一下就知道了

clip_image008

先定义一个变量count,然后分别使用forkvfork函数创建进程执行看。

对于fork,执行效果

clip_image010

输出count两次,结果都是1。一个父进程打印的,一个是子进程打印的,但是要注意,不能确定执行谁先谁后。由于fork有自己的数据段和堆栈,所以父进程和子进程的count变量相互不影响。

对于vfork,执行效果

clip_image011

         结果和fork的不一样了,也是打印两次,第一个是子进程打印的,第二个是父进程打印的,注意打印的顺序是确定的,因为vfork创建子进程后,是子进程先运行,运行结束后,父进程才运行,和fork就不一样了。

         其次,打印的值也不一样。因为对于vfork创建的子进程,子进程与父进程共享数据段,堆栈,所以对于count变量,父子进程使用的都是同一个,所以结果就是如上了。