Linux环境编程--如何用C语言创建多进程运行以及简单的pipe管道使用
进程:
每一个进程都有一个非负整数表示的唯一进程ID。当一个进程终止后,其进程ID就成为复用的候选者,大多数UNIX系统实现延时复用算法,使得赋予新建进程的ID不同于最近终止进程所使用的ID,防止将新进程误认为某个先前终止的进程。
创建多进程:
这里就需要调用命令fork()或者vfork()
fork():
一个现有的进程可以调用fork()系统调用用来创建一个新的进程:
pid_t fork(void);
由fork()创建的新进程被称为子进程。
1,子进程可以通过getpid()和getppid()分别获取自己的进程ID和父进程ID,所以返回0;
2,一个父进程可以有很多个子进程,没有一个系统调用可以获取所有的子进程ID,所以需要将子进程的ID通过返回值的形式传递给父进程。
子进程是父进程的副本,它将得到父进程的文本段、数据段、堆和栈副本,这样父子进程都将继续执行fork()之后的代码。但父子进程并不共享这些存储空间,父子进程只是共享文本段。
新创建的父子进程谁先执行没有规定,由系统调用决定。
注:
1.fork()函数被调用一次,但有两次返回。
2.返回值
=0: 子进程
>0:父进程
<0:出错
3.新创建的父子进程谁先执行没有规定,由系统调用决定。
4.如果在子进程中调用了exit(),那么退出的是子进程。
程序例子:
目的:打印出父、子进程的进程号以及验证父进程是否真的将自己的数据拷贝一份给子进程
说明:
由于进程的调度有系统决定,因此子进程先执行还是父进程先执行是无法确定的,所以为了避免子进程还没来得及运行时,父进程关闭,通常在父进程当中加个简单的延时sleep(),但这也不是100%保证一定子进程先执行。
运行结果:
PID = 29332为子进程的进程号,并且全局变量g_val(代表数据段中的数据)和局部变量var(代表栈中数据)全部加1,父进程没有变化。也就说明了,父进程确实将数据拷贝给子进程,并且子进程的数据处理与父进程无关,完全是2个独立的内存。
pipe管道:
一个管道有2个口子
这种是针对有血缘关系的进程之间,完成数据传输。
1.例如:父进程调用了pipe()再fork()之后,子进程会继承父进程的pipe()
此时有2条管道,4个口子。如果要进自行父子单向数据传输,则需要关闭特定的2个口子。父进程要写给子进程,则关闭父 进程的读,关闭子程序的写。子进程要写给父进程则相反
2.规定了fd[2]中 0->r 1->w
利用pipe管道和fork()结合进行父子程序之间的通讯实例:
目的:创建子进程,并利用子程序调用execl去执行Linux命令ifconfig打印出eth0这个网口的信息
运行结果: