weiqi7777

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

0
阅读(2183)

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

4.1创建进程

4.1.1函数名

fork

4.1.2函数原形

pid_t fork(void)

4.1.3函数功能

创建子进程

4.1.4所属头文件

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所属头文件

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所属头文件

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所属头文件

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变量,父子进程使用的都是同一个,所以结果就是如上了。

Baidu
map