fork()与CreateProcess()。系统调用与API?

时间:2015-07-30 16:03:30

标签: api winapi fork posix system-calls

假设API通常与系统调用类似(在某些情况下相同),它们会调用....

我们在用户应用程序中调用了 fork(),这是POSIX'中的一个API。它会调用实际系统调用' fork()' ?或者我们直接调用 fork() 系统调用?

它与Win32 API中的 CreateProcess()相比如何?

CreateProcess() 系统调用,它调用另一个系统调用 NTCreateProcess()系统调用或 CreateProcess()< / em> Win32 API中的一个函数调用 NTCreateProcess()系统调用?

2 个答案:

答案 0 :(得分:2)

我只能说Linux和UNIX变种,但我想Windows与之类似。

  

我们在用户应用程序中调用fork(),即“POSIX中的API”   它调用实​​际的系统调用'fork()'?或者我们直接做   调用fork()系统调用?

在Linux中,fork(2)是系统调用,但最近的Linux版本在大多数情况下不使用它。当您从C用户程序调用{​​{1}}时,您正在调用glibc包装器,而不是真正的系统调用 - 从最新版本开始,glibc包装器调用fork(2)并向其传递必要的标志以指示新流程的属性。 clone(2)是真正的系统调用(请参阅clone(2))。

但是,即使您直接在C程序中调用man 2 clone,您也将调用glibc包装函数。大多数原始系统调用在glibc中都有一个等效的包装函数,因为原始系统调用是依赖于体系结构的。

一些联机帮助页包括两者的原型,包装器和原始系统调用。例如,clone(2)的联机帮助页显示了两种变体:

clone(2)

您通常可以从联机帮助页中学到很多东西。 SYNOPSIS /* Prototype for the glibc wrapper function */ #include <sched.h> int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ... /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ ); /* Prototype for the raw system call */ long clone(unsigned long flags, void *child_stack, void *ptid, void *ctid, struct pt_regs *regs); 提到了我在上面的注释部分所说的内容:

  

注意

     

在Linux下,fork()是使用copy-on-write实现的   页面,所以它产生的唯一惩罚是时间和记忆   需要复制父页面表,并创建一个唯一的   孩子的任务结构。

     

从版本2.3.3开始,而不是调用内核的fork()系统   调用,作为NPTL的一部分提供的glibc fork()包装器   线程实现使用提供的标志调用clone(2)   与传统系统调用相同的效果。 (对fork()的调用是                                                                等效于对clone(2)的调用,将标志指定为SIGCHLD。)glibc包装器调用任何fork处理程序   已经使用pthread_atfork(3)建立。

(如果您想知道,NPTL代表Native POSIX Threads Library

TL; DR当你编程时,你永远不会直接调用系统调用。您调用glibc包装器来处理原始系统调用调用的细节。

答案 1 :(得分:0)

正如Jeffy Coffin所指出的,API代表应用程序接口,是一个描述应用程序使用的一组函数,相关类型和其他语言接口和功能的文档。 API几乎可以是任何东西。例如,Stack Exchange具有web API,任何能够通过Internet发出HTTP请求的东西都可以使用它。

另外,正如Jerry Coffin所说的“系统调用”一词&#34;没有很好的定义。它只是一个实现操作服务的API函数。您可能会认为CreateProcess和NTCreateProcess都不是系统调用。两者都是围绕真正系统调用的C包装器,它是用汇编语言编写的位代码。另一方面,我认为他们都是系统调用。它们都提供对操作系统设施的访问,以创建没有重要额外功能的新流程。无论哪种方式,它都不重要。