vfork用于创建一个新进程,而该新进程的目的是exec一个新进程,
vfork和fork一样都创建一个子进程,但是它并不将父进程的地址空间
完全复制到子进程中,因为子进程会立即调用exec,于是也就不会存放该地址空间。不过在子进程中调用exec或exit之前,他在父进程的空间中运行。
vfork和fork之间的另一个区别是: vfork保证子进程先运行,在她调用exec或exit之后
父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作
,则会导致死锁。
用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序,
当进程调用一种exec函数时,该进程完全由新程序代换,而新程序则从其main函数
开始执行,因为调用exec并不创建新进程,所以前后的进程id 并未改变,exec只是用
另一个新程序替换了当前进程的正文,数据,堆和栈段。
例子1:用fork创建子进程
#include "apue.h"
int glob = 6; /* external variable in initialized data */
int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid;
var = 88;
printf("before vfork\n"); /* we don't flush stdio */
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
glob++; /* modify parent's variables */
var++;
_exit(0); /* child terminates */
}
/*
* Parent continues here.
*/
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
exit(0);
}
输出:
a write to stdout
before fork
pid = 3130,glob = 6,var = 88
pid = 3131,glob = 7,var = 89
这里printf一次,但却输出两次,为什么?
用fork创建的子进程会产生父进程的副本,即子进程会copy调用fork函数后的代码断,本例子中子进程拥有:
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
exit(0);
同样父进程也拥有:
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
exit(0);
当每一个进程终止时,其缓存中的内容被输出。
例子2:用vfork创建子进程
#include "apue.h"
int glob = 6; /* external variable in initialized data */
int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid;
var = 88;
printf("before vfork\n"); /* we don't flush stdio */
if ((pid = vfork()) < 0) {
err_sys("vfork error");
} else if (pid == 0) { /* child */
glob++; /* modify parent's variables */
var++;
_exit(0); /* child terminates */
}
/*
* Parent continues here.
*/
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
exit(0);
}
输出:
a write to stdout
before fork
pid = 3169,glob = 7,var = 89
分享到:
相关推荐
在Linux操作系统中,`fork()`、`vfork()` 和 `clone()` 都是用于创建新进程的函数,但它们在实现机制和使用场景上存在显著差异。 1. **fork()** `fork()` 是最传统的进程创建方法。它创建一个与父进程完全独立的新...
这个程序是为了分析fork()函数和vfork()函数的区别,使用的系统环境是linux
功能说明 strace 命令是一种强大的工具, 能够显示任何由用户空间程式发出的系统调用....-f -F选项告诉strace同时跟踪fork和vfork出来的进程 -o xxx.txt 输出到某个文档. -e execve 只记录 execve 这类系统调用.
在提供的文档 "vfork和fork.doc" 中,可能详细讲述了这两个函数的工作原理、使用方法以及一些示例代码。这些示例通常会展示如何正确地调用 `vfork()` 或 `fork()`,以及如何处理它们返回的结果来区分父进程和子进程...
fork 函数与 vfork 函数的区别在于:vfork 函数创建的子进程会在父进程的地址空间中执行,而不是在自己的地址空间中执行。这意味着,vfork 函数创建的子进程不能修改父进程的地址空间。 在使用 fork 函数时,为什么...
进程间的交互和控制是通过一系列特定的系统调用来实现的,其中`fork()`、`vfork()`和`execX()`(包括`execl`, `execle`, `execv`, `execve`, `execlp`, 和 `execvp`)是非常重要的进程控制函数。下面我们将深入解析...
3,要求分别用fork和vfork创建子进程。 实验五 创建子进程一,在子进程中递归打印/home目录中的内容(用exec系列函数调用第二次实验中的代码完成此功能); 1.子进程结束的时候完成以下功能: 打印字符...
"Linux进程编程介绍.pdf"可能涵盖了以下内容:进程创建(fork和vfork函数)、进程终止(exit和wait函数)、进程间通信(IPC,包括管道、消息队列、共享内存和信号量)、进程状态(如运行、就绪和阻塞)以及进程调度...
这部分内容涵盖了进程创建(fork和vfork)、进程执行(exec系列函数)、进程间通信(管道、套接字、信号量、消息队列等)、进程状态和调度策略。还可能讨论了进程组和会话的概念,以及孤儿进程和僵死进程的处理。 ...
Linux内核提供了完整的进程生命周期管理API,其中包括创建进程的fork和vfork,以及执行新程序的exec系列函数。此外还有控制进程状态的函数如nice、getpriority、setpriority等,以及控制进程资源使用的setrlimit、...
在Linux操作系统中,`vfork()`和`fork()`都是创建新进程的系统调用,但它们之间存在着显著的差异。本篇文章将深入探讨`vfork()`的原理、特点以及与`fork()`的区别,并通过C语言的源代码示例进行解析。 `vfork()`是...
20. fork和vfork的区别: fork用于创建一个子进程,它复制父进程的地址空间。vfork也用于创建子进程,但不复制地址空间,子进程共享父进程的数据段和堆栈段。 21. 并发和并行: 并发是指两个或多个事件在同一时间段...
* -f 选项告诉 Strace 同时跟踪 fork 和 vfork 出来的进程 * -o 选项输出到某个文件 * -e 选项只记录 execve 这类系统调用 Strace 命令的使用方法大体相同,下面仅介绍三者共有的三个命令行参数: * -f 选项除了...
打通Linux脉络系列:进程、线程和调度 ...2.1 fork 和 vfork 区别 2.2 写时拷贝技术 2.3 Linux线程的实现本质 2.4 孤儿进程的托孤,SUBREAPER 练习题 第三部分大纲 练习题 第四部分大纲 练习题
Linux操作系统中的`fork`和`vfork`都是用于创建新进程的系统调用,它们都是在父进程中创建一个与父进程几乎完全一样的子进程。然而,`vfork`和`fork`之间存在着一些显著的区别。 1. **fork基础了解**: `fork`函数...
概括 sfork是Linux上新系统调用的原型,它为启动进程提供了同步的单线程接口。 sfork可以看作是vfork一种变体,它做了... 但是,与传统的fork和vfork , sfork只会返回一次。 sfork成功时总是返回0,如果由于任何通常
一、描述进程——PCB ·进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合 ·我们称为PCB,Linux操作系统下的PCB是:task struct 2、task_struct——PCB的一种 ·在Linux中描述进程的结构体...