1. fork()系统调用
Linux下可以通过fork()系统调用来创建一个子进程,fork,英文解释就是“分叉”,当我们通过系统调用fork(),就创建了一个子进程。fork()系统调用有两个返回值,其中一个返回给父进程,其返回值是子进程的PID(process id),另一个返回给子进程,其返回值是0。所以可以通过其返回值来判断当前的代码是在父进程还是子进程运行,如果其返回值大于0,说明在父进程运行,如果fork()系统调用的返回值等于0,说明在子进程运行,如果小于0,说明fork()出错。
一个子进程只有一个父进程,且所有进程都可以通过getpid()来获取其pid,也可以通过getppid()来获取其父进程的pid。
一个进程可以有多个子进程,对于父进程而言,并没有一个函数来得知其子进程的pid,所以父进程在创建子进程时子进程返回其子进程号给父进程。
fork()系统调用会创建一个子进程,这个子进程是父进程的一个副本,父进程会将其代码段,数据段和堆栈段都复制一份给子进程,但子进程有自己的内存空间,子进程对其内存空间的修改并不会影响到父进程的内存空间。这时就会有两个相近的父子进程,父子进程的先后执行并没有固定的顺序。如果想要父子进程按照一定的先后顺序执行,就需要使用进程间通信的方式。
通过一个实例来看父子进程的运行过程:
如上面程序所示,fork()系统调用创建一个子进程,在子进程中改变全局变量g_var的值,由fork()的返回值可知,如果父进程先运行,则使父进程sleep 2 秒,使子进程运行,在子进程中改变了g_var 的值,然后子进程继续运行,到代码第32行子进程退出。接着父进程运行,也同样在第32行父进程退出。对比运行结果,g_var的值先后不一样,第一次输出8,因为在子进程中将其自加,第二次输出7,因为父进程中并没有改变g_var的值。由此可见,父子进程对数据的处理是相互独立的,子进程对其自己的数据的操作,并不会影响到父进程。