<代码>fork和exec
之间有何区别?
使用<代码>fork和exec
体现了UNIX的精神,因为它为启动新进程提供了非常简单的途径。
<条码>fork 电话基本上重复了目前的工作,在a 近上完全相同。 并非所有事项都得到复制(例如,有些执行中的资源有限),但想法是尽可能贴近一份副本。
新的程序(儿童)有不同的程序,并且将旧程序(父母)作为其父母程序信息数据库。 由于这两个过程目前完全是相同的法典,他们可以说明,根据<条码>
<代码>exec 呼吁基本上是用新的方案取代目前整个进程的一种方式。 该方案将该方案装入目前的程序空间,从切入点开始。
因此,fork
和exec
经常被按顺序使用,以获得一个新方案,作为现行程序的儿童。 每当你试图实施<条码>限定的条码>等方案时,壳牌人通常会这样做,然后把<条码>限定的<>条码”方案装入记忆,提出所有指挥线论点、标准I/O等等。
但是,它们不需要一起使用。 它完全为<代码>fork的方案所接受。 例如,如果方案包含父母和子女法(需要仔细做些什么,每项执行都可能有限制),则没有<条码>exec。 大量(而且现在)用于 da,这些ons只聆听了TCP港口和fork
,在父母回听时自行处理具体请求。
同样,知道这些方案已经结束,而且只是想实施另一个方案,不需要<>fork,exec
, 然后,wait
。 他们只能将儿童直接装入其处理空间。
某些UNIX的实施有优化的fork
,其中使用了它们称之为的正文。 这是在节目试图改变这一空间之前,将程序空间的复制延迟到fork
。 这些方案只使用<条码>fork,而不是<条码>exec,因为它们不必复制整个过程空间。
如果exec
is >在fork
(而且情况大多)后面插入exec
>>,就会给处理空间带来文字,然后复制用于儿童工作。
请注意,exec
calls (execl/code>,
execle
,
execve
, 等,exec
, in context here means any of them.
以下图表显示典型的<代码>fork/exec操作,bash
a. 壳体为<代码>ls的目录:
+--------+
| pid=7 |
| ppid=4 |
| bash |
+--------+
|
| calls fork
V
+--------+ +--------+
| pid=7 | forks | pid=22 |
| ppid=4 | ----------> | ppid=7 |
| bash | | bash |
+--------+ +--------+
| |
| waits for pid 22 | calls exec to run ls
| V
| +--------+
| | pid=22 |
| | ppid=7 |
| | ls |
V +--------+
+--------+ |
| pid=7 | | exits
| ppid=4 | <---------------+
| bash |
+--------+
|
| continues
V
fork(
>将现行程序分成两个过程。 换言之,你很容易思考方案,突然成为两个单独的方案,执行一个法典:
int pid = fork();
if (pid == 0)
{
printf("I m the child");
}
else
{
printf("I m the parent, my child is %i", pid);
// here we can kill the child, but that s not very parently of us
}
这可能给你造成沉重的印象。 现在,有一部法典,两个程序执行的情况大致相同。 儿童过程继承了所有法典,并缅怀刚刚建立起来的进程,包括从<条码>fork(<>>>>/代码>上删除。 唯一的区别是fork(>
>,如果是父母或子女,请通知您。 如果是父母,其回报价值就是子女。
exec>/code>是易于掌握的比喻,你仅指
exec
,以使用目标可执行的程序,而且你没有两种程序可操作同一守则或继承同一国家。 同@Stevekinins 一样,exec
可在fork
之后使用,以便在目前过程中执行可执行的目标。
我认为,从到Marc Rochkind的“推进式设计”的一些概念有助于理解fork(
>exec(>,,特别是用于Windowscode>的人:
<
program/em>是定期保存在磁盘上的指令和数据的收集。 (由1。1。2方案、工艺和校对)
。
In order to run a program, the kernel is first asked to create a new process, which is an environment in which a program executes。 (also from 1。1。2 Programs, Processes, and Threads)
。
It’s impossible to understand the exec or fork system calls without fully understanding the distinction between a process and a program。 If these terms are new to you, you may want to go back and review Section 1。1。2。 If you’re ready to proceed now, we’ll summarize the distinction in one sentence: A process is an execution environment that consists of instruction, user-data, and system-data segments, as well as lots of other resources acquired at runtime, whereas a program is a file containing instructions and data that are used to initialize the instruction and user-data segments of a process。 (from 5。3
exec
System Calls)
一旦了解方案与程序之间的区别,可归纳如下:
fork()
creates a duplicate of the current processexec()
replaces the program in the current process with another program
(this is essentially a simplified for dummies version of paxdiablo s much more detailed answer)
Fork creates a copy of a calling process. generally follows the structure
int cpid = fork( );
if (cpid = = 0)
{
//child code
exit(0);
}
//parent code
wait(cpid);
// end
(for child process text(code),data,stack is same as calling process) child process executes code in if block.
EXEC replaces the current process with new process s code,data,stack. generally follows the structure
int cpid = fork( );
if (cpid = = 0)
{
//child code
exec(foo);
exit(0);
}
//parent code
wait(cpid);
// end
(after exec call unix kernel clears the child process text,data,stack and fills with foo process related text/data) thus child process is with different code (foo s code {not same as parent})
它们正在共同使用,以建立一个新的儿童进程。 第一,电话fork
制作一份现行程序(儿童进程)的副本。 然后,从儿童程序中传到“将”父母程序的副本与新程序相“替换”。
这一进程类似:
child = fork(); //Fork returns a PID for the parent process, or 0 for the child, or -1 for Fail
if (child < 0) {
std::cout << "Failed to fork GUI process...Exiting" << std::endl;
exit (-1);
} else if (child == 0) { // This is the Child Process
// Call one of the "exec" functions to create the child process
execvp (argv[0], const_cast<char**>(argv));
} else { // This is the Parent Process
//Continue executing parent process
}
fork(
和exec(
)之间的主要区别是:
The fork()
system call creates a clone of the currently running program. The original program continues execution with the next line of code after the fork() function call. The clone also starts execution at the next line of code.
Look at the following code that i got from http://timmurphy.org/2014/04/26/using-fork-in-cc-a-minimum-working-example/
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
printf("--beginning of program
");
int counter = 0;
pid_t pid = fork();
if (pid == 0)
{
// child process
int i = 0;
for (; i < 5; ++i)
{
printf("child process: counter=%d
", ++counter);
}
}
else if (pid > 0)
{
// parent process
int j = 0;
for (; j < 5; ++j)
{
printf("parent process: counter=%d
", ++counter);
}
}
else
{
// fork failed
printf("fork() failed!
");
return 1;
}
printf("--end of program--
");
return 0;
}
该方案宣布了一个反变量,在fork()
之前为零。 在发出呼吁后,我们有两个进程同时进行,既增加了自己的反照。 每个进程都将完成和退出。 由于这些进程同时进行,我们无法知道哪些进程将首先完成。 开办这一方案将印刷类似于下文所示内容的内容,但结果可能因不同而异。
--beginning of program
parent process: counter=1
parent process: counter=2
parent process: counter=3
child process: counter=1
parent process: counter=4
child process: counter=2
parent process: counter=5
child process: counter=3
--end of program--
child process: counter=4
child process: counter=5
--end of program--
“exec(>
family of system calls 改为“一个过程的现行执行守则”,代之以另一部守则。 这一过程保留了项目信息数据库,但成为新的方案。 例如,考虑以下法典:
#include <stdio.h>
#include <unistd.h>
main() {
char program[80],*args[3];
int i;
printf("Ready to exec()...
");
strcpy(program,"date");
args[0]="date";
args[1]="-u";
args[2]=NULL;
i=execvp(program,args);
printf("i=%d ... did it work?
",i);
}
该方案称为execvp()
功能,将其代码改为日期方案。 如果该守则存放在一份名为“前身1.c”的档案中,则执行该守则会产生以下产出:
Ready to exec()...
Tue Jul 15 20:17:53 UTC 2008
方案产出如下:Ready to exec() .‖,在称为前列功能之后,将其代码改为日期方案。 请注意,由于当时该法典已被取代,因此没有显示该行——它的确是干.。 相反,我们看到执行的产出——日期-u.‖。
Fork(k)(a) 制作一份目前程序的副本,在新儿童执行死刑的时间从点(k)呼吁开始。 for后,除 for(k)功能的回报价值外,还重新统一。 (详情见RTFM)。 两个进程随后可能进一步分歧,一个进程不能干预另一个进程,除非可能通过任何共同档案处理。
前言 它与k(k)没有任何关系,但外阴(外阴)在人们想要启动不同的儿童进程而不是取代目前的儿童进程时,通常会 follows。
它制作了一个运行过程的副本。 运行过程称为 父母程序 & 新成立的程序称为儿童进程。 区分二者的方法是研究返还价值:
fork(
> 回归父母程序中的儿童过程识别符号(pid)http://www.ohchr.org。
www.un.org/Depts/DGACM/index_french.htm
它在一个进程中启动了新的进程。 它把新方案装入目前的进程,取代现有的方案。
www.un.org/Depts/DGACM/index_french.htm
在启动新方案时,首先要fork(
>,创建新程序,然后是exec(>
(即装入记忆和执行)方案本应用于运行。
int main( void )
{
int pid = fork();
if ( pid == 0 )
{
execvp( "find", argv );
}
//Put the parent to sleep for 2 sec,let the child finished executing
wait( 2 );
return 0;
}
了解<代码>fork(和exec(
) 概念的主要实例是<>shell<<>>>>>>, 用户通常在系统录入后执行的传译方案。 页: 1 姓名
在许多指挥机关中,shell <>>><>>>>>>>> > >forks/strong><>>>>和“儿童过程<>>>>><>>>>>>>>> 指挥官把指挥线上的其余词作为指挥参数。
The shell allows three types of commands. First, a command can be an executable file that contains object code produced by compilation of source code (a C program for example). Second, a command can be an executable file that contains a sequence of shell command lines. Finally, a command can be an internal shell command.(instead of an executable file ex->cd,ls etc.)
- winforms
- combobox
- fogbugz
- java
- date
- internationalization
- asp.net
- iis
- url-rewriting
- urlrewriter
- c#
- enums
- ocaml
- haxe
- algorithm
- string
- viewstate
- .net
- c++
- c
- symbol-table
- mysql
- database
- postgresql
- licensing
- migration
- vb.net
- vb6
- declaration
- vb6-migration
- python
- psycopg2
- backup
- vmware
- virtualization
- gnu-screen
- authentication
- desktop
- excel
- xll
- cultureinfo
- regioninfo
- oracle
- client
- session
- download
- html
- virtual
- constructor
- scenarios
- perl
- full-text-search
- javascript
- ajax
- testing
- oop
- inheritance
- vim
- encapsulation
- information-hiding