初步认识Unix系统中的Fork()函数

1.Fork()函数的简单介绍

fork()是一个系统调用,用于创建一个独立于主进程的子进程。创建的这个子进程与主进程基本一致。一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把主进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同,相当于复制了另一个“自己”。虽说如此,但是主进程在调用fork()之前的代码,子进程并没有执行,子进程只是复制了主进程的数据罢了。

2.Fork()函数的返回值

  1. 在父进程中,fork返回新创建子进程的进程ID;
  2. 在子进程中,fork返回0;
  3. 如果出现错误,fork返回一个负值;

通过fork()的返回值我们可以快速地区分主进程和子进程。

3.fork()函数的特性

我们先看一段代码:

1	int main()
2	{
3		pid_t pid;
4		int x = 1;
5
6		pid = Fork();
7		if(pid = 0){/* Child */
8			printf("child : x=%d\n",++x);
9			exit(0);
10		}
11
12		/* Parent */
13		printf("parent : x=%d\n",--x);
14		exit(0);
15	}

这段代码的输出结果是:
parent : x=0
child : x=2

fork()函数具有以下几个特性:

1.调用一次,返回两次

在上面这个例子中,我们调用了一次fork()函数,但是却返回了两个值。

2. 并发执行

如果我们执行多次上面的代码,我们会发现有时候输出顺序会反过来,这是由于主进程和子进程是并发进行的独立进程,内核能够以任意方式交替执行两个进程,因此输出结果完全是随机的。

3. 相同但是独立的地址空间

相同是指子进程与主进程具有相同的用户栈、相同的本地变量值、相同的堆、相同的全局变量值,以及相同的代码。所以在上面的例子中,当fork()在第6行返回时,主进程和子进程中的本地变量x的值都为1。
独立是指主进程和子进程的运行都是独立的。在上面的例子中,由于主进程和子进程是相互独立的,因此主进程和子进程对x所做的任何改变都是独立的,这也就是为什么当主进程和子进程各自调用它们的printf语句时,输出的结果不同了。

4.共享文件

当我们运行这个程序时,我们会发现主进程和子进程都把它们的输出显示在屏幕上,原因是子进程继承了主进程的所有打开文件。

4.fork()函数的简单例子

下面看一段代码:

1	int mian()
2	{
3		int x = 1;
4		
5		if(Fork() == 0)
6			printf("p1: x=%d\n",++x);
7		printf("p2: x=%d\n",--x);
8		exit(0);
9	}

我们一起来简单地分析一下。首先,主进程在第5行的时候调用了Fork()函数,这时创建了一个子进程,此时主进程和子进程的x的值都为1;

在子进程中,fork()返回的值为0,调用if下面的printf语句,x先加1,然后输出:p1: x=2;随后执行第二个printf语句,x减1,然后输出:p2: x=1;最后退出。

在主进程中,由于fork()返回的值不为0,所以跳过if,直接执行第二个printf语句,x先减1,然后输出:p2: x=0;最后退出。

因此主进程的输出为:
p2: x=0
子进程的输出为:
p1: x=2
p2: x=1

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值