简述fork函数的用法
来源:互联网 发布:虚拟机中linux怎么联网 编辑:程序博客网 时间:2024/06/06 02:30
1、fork函数的定义
头文件:
#include<unistd.h>
#include<sys/types.h>
函数原型:
pid_t fork( void);
(pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)
返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
函数说明:
一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。
UNIX将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。在不同的UNIX (Like)系统下,我们无法确定fork之后是子进程先运行还是父进程先运行,这依赖于系统的实现。所以在移植代码的时候我们不应该对此作出任何的假设。
2、函数特点和进阶
从上面的函数说明里面可以看到fork函数会有几个特点:
(1)返回两个值不同的值代表不同的意思。
(2)子进程获得父进程的数据空间和堆栈等资源并且独立的。
举个简单的例子如下:
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t fpid;//fpid表示fork函数返回的值
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0)
printf("I am the child process, my process id is %d\n", getpid());
else
printf("I am the parent process, my process id is %d\n", getpid());
return 0;
}
#include <stdio.h>
int main()
{
pid_t fpid;//fpid表示fork函数返回的值
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0)
printf("I am the child process, my process id is %d\n", getpid());
else
printf("I am the parent process, my process id is %d\n", getpid());
return 0;
}
这个例子最中的结果为:
I am the parent process, my process id is 11594
I am the child process, my process id is 11595
I am the child process, my process id is 11595
可以明显看出来个不同进程的不同打印出来了,具体打印什么要看linux系统的调度算法了。main函数在fork之后变成了两个进程。可以各自干各自的事情。
第二个例子:
int main()
{
pid_t fpid;//fpid表示fork函数返回的值
printf("fork!");
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0)
printf("I am the child process, my process id is %d\n", getpid());
else
printf("I am the parent process, my process id is %d\n", getpid());
return 0;
}
{
pid_t fpid;//fpid表示fork函数返回的值
printf("fork!");
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0)
printf("I am the child process, my process id is %d\n", getpid());
else
printf("I am the parent process, my process id is %d\n", getpid());
return 0;
}
这个例子比第一个例子多了一个printf(fork!");
这个例子的输出结果为:
fork!I am the parent process, my process id is 11852
fork!I am the child process, my process id is 11853
fork!I am the child process, my process id is 11853
上面的例子你会看到一个现象:子进程继承了父进程的数据空间,导致子进程和父进程都输出了fork!。但是如下如果加上\n
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t fpid;//fpid表示fork函数返回的值
printf("fork!\n");
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0)
printf("I am the child process, my process id is %d\n", getpid());
else
printf("I am the parent process, my process id is %d\n", getpid());
return 0;
}
#include <stdio.h>
int main()
{
pid_t fpid;//fpid表示fork函数返回的值
printf("fork!\n");
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0)
printf("I am the child process, my process id is %d\n", getpid());
else
printf("I am the parent process, my process id is %d\n", getpid());
return 0;
}
输出结果:
fork!
I am the parent process, my process id is 11950
I am the child process, my process id is 11951
I am the parent process, my process id is 11950
I am the child process, my process id is 11951
此时结果只有一个fork!打印了,这是为什么呢?这是因为prinf的行数据缓冲问题,在没有加\n的时候数据是在缓冲区中,没有直接输出到stdout,当加上\n的时候数据会刷新输出到stdout。所以出现了上面的情况。
再列举一个简单的例子:
#include <unistd.h>
#include <stdio.h>
int main ()
{
pid_t fpid; //fpid表示fork函数返回的值
int count=0;
fpid=fork();
if (fpid < 0)
printf("error in fork!\n");
else if (fpid == 0) {
printf("i am the child process, my process id is %d\n",getpid());
printf("child\n");
count++;
}
else {
printf("i am the parent process, my process id is %d\n",getpid());
printf("parent\n");
count++;
}
printf("%s, %d, %d\n", __FUNCTION__, __LINE__,count);
return 0;
}
#include <stdio.h>
int main ()
{
pid_t fpid; //fpid表示fork函数返回的值
int count=0;
fpid=fork();
if (fpid < 0)
printf("error in fork!\n");
else if (fpid == 0) {
printf("i am the child process, my process id is %d\n",getpid());
printf("child\n");
count++;
}
else {
printf("i am the parent process, my process id is %d\n",getpid());
printf("parent\n");
count++;
}
printf("%s, %d, %d\n", __FUNCTION__, __LINE__,count);
return 0;
}
输出结果为:
i am the parent process, my process id is 12163
parent
main, 92, 1
i am the child process, my process id is 12164
child
main, 92, 1
parent
main, 92, 1
i am the child process, my process id is 12164
child
main, 92, 1
这个例子清晰的看到count是子进程从父进程获取到的独立的栈数据,在输出的时候分别都是1,而不是2。
3、fork出错可能有两种原因:
1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
2)系统内存不足,这时errno的值被设置为ENOMEM。
1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
2)系统内存不足,这时errno的值被设置为ENOMEM。
上述简单介绍fork函数的用法,后续继续讲解fork和vfork函数的区别。
- 简述fork函数的用法
- fork函数的用法
- fork()函数的用法
- fork函数的用法总结
- fork()函数的基本用法
- linux/Unix中fork函数的用法
- linux中fork()函数的用法详解
- fork()函数用法理解
- linux下fork()函数用法
- linux并发端口扫描以及fork()函数的用法;
- fork的用法实例
- Java中Split函数的用法技巧--简述
- 简述UIDatePicker的用法
- 简述UIDatePicker的用法
- fork()和vfork()的区别,signal函数用法,exec()系列函数的用法小结
- fork函数的剖析
- FORK()函数的理解
- FORK()函数的理解
- 添加spring的bean.xml代码自动提示
- 快捷开发之——二维码扫描,定制二维码扫描页面
- iOS UIPageControl的简单使用
- 我的spring学习日记 - bean-1
- 观察者模式
- 简述fork函数的用法
- i++和++i
- linux下-rwxr-xr-x 1 root root 702160 2008-05-12 11:33 bash含义
- OCP-1Z0-053-V12.02-46题
- 充实
- Tree's Depth(二叉树)
- NYOJ58最小步数(神搜)
- 【D3.js数据可视化系列教程】(十八)--组合添加删除
- C内存申请释放