假设API通常与系统调用类似(在某些情况下相同),它们会调用....
我们在用户应用程序中调用了 fork(),这是POSIX'中的一个API。它会调用实际系统调用' fork()' ?或者我们直接调用 fork() 系统调用?
它与Win32 API中的 CreateProcess()相比如何?
是 CreateProcess() 系统调用,它调用另一个系统调用 NTCreateProcess()系统调用或 CreateProcess()< / em> Win32 API中的一个函数调用 NTCreateProcess()系统调用?
答案 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包装器,它是用汇编语言编写的位代码。另一方面,我认为他们都是系统调用。它们都提供对操作系统设施的访问,以创建没有重要额外功能的新流程。无论哪种方式,它都不重要。