2010-04-19 97 views
24

系统调用和函数调用有什么区别? fopen()是系统调用还是函数调用?系统调用vs函数调用

+9

Stackoverflow警察来了!这个问题似乎有效。你是否考虑过某人没有参加课程,但有这个疑问? – Tom 2010-04-19 15:59:54

+6

即使这是一个家庭作业问题,研究是关于提出正确的问题,他将不得不将这个页面上的所有答案提炼成一个正确的答案。如果他不了解内容,他会无论如何将其搞砸。它没有什么不妥之处。 – 2010-04-19 16:10:50

回答

1

fopen是一个函数调用,但它有时可能被称为系统调用,因为它最终由“系统”(OS)处理。 fopen内置于C runtime library

9

fopen是一个函数调用。

系统调用与管理资源的底层操作系统进行交互。它的次序比函数调用更昂贵,因为必须采取许多步骤来保存进行系统调用的进程的状态。

在* nix系统上,fopen wrap打开,这会使系统调用(open是系统调用的C-wrapper)。 fread/read,fwrite/write等等也会发生同样的情况。

Here这里有一个unix系统调用执行任务的很好的描述。

+1

它在* nix系统上封装了'open',但它在其他操作系统上封装了不同的系统调用(例如Windows上的'CreateFile')。 – 2010-04-19 15:56:40

+0

是的,我在Windows上运行C或C++,所以我总是不考虑它。 (完全教条式的,我知道) – Tom 2010-04-19 15:58:30

+0

考虑到windows有很多C/C++(考虑到专业CAD /办公软件和视频游戏),如果不是更多的话,这是很荒谬的。 Visual Studio对C/C++来说并不是那么糟糕。 – 2010-04-19 16:02:36

26

系统调用是对内核代码的调用,通常通过执行中断来执行。中断导致内核接管并执行请求的操作,然后将控制权交还给应用程序。这种模式切换是系统调用执行速度慢于等效应用程序级功能的原因。

fopen是C库中的一个函数,它在内部执行一个或多个系统调用。一般来说,作为C程序员,你很少需要使用系统调用,因为C库为你包装它们。

+1

'这种模式切换是系统调用执行速度比等效的应用程序级别函数慢的原因.'这并不意味着fopen()比使用相关系统调用执行相同的操作更快吗?因为如果'fopen()'已经在执行系统调用来完成它的工作,那么在最坏的情况下,使用相关系统调用必须以'fopen()'正确的速度运行? – Utku 2016-05-11 15:50:55

+2

对。 'fopen()'可能会比自己调用系统稍微慢一点,但通过使用'fopen()'你可以获得可移植性,可读性和可维护性。 – Thomas 2016-05-12 08:53:30

+0

缓存和缓冲函数调用速度更快的主要原因。我真的是一个知识有限的初学者。你对此有何想法? – adityah 2017-08-19 02:38:29

2

System call实际调出一个由内核空间执行的API。具有此假设的所有相关成本(请参阅Wiki或此链接以了解详细信息)

函数调用是调用用户空间中的一段代码。

但是,请注意函数调用MIGHT是一个函数,它在执行过程中会执行系统调用 - “fopen”就是这样的例子之一。因此,虽然对fopen本身的调用是对函数的调用,但这并不意味着系统调用不会处理实际的IO。

2

增加这个讨论的一个观点是,通常在最乐观情况下的函数调用在x86中具有几个8位指令(平均为4-10)的开销。

系统调用具有以下属性。

  1. 它执行更多的指令,它必须冻结一个进程而不是简单的堆栈状态。
  2. 涉及的时间大多是非确定性的。
  3. 它通常是一个调度点,调度程序可能会选择重新计划。

对于这三个原始原因(可能更多),应尽可能减少系统调用的数量 - 例如,网络系统软件保持套接字句柄(以及连接使用的其他应用程序特定的内部数据结构)分配给新的连接,为什么打扰内核?

请记住,软件是建立在一个颠倒的金字塔。系统调用在基地。

+0

此外,系统调用是否将虚拟内存映射到物理内存? – qub1n 2015-10-14 20:42:24

1

只是为了完成其他人提供的图片,fopencommonly implemented作为围绕open的包装,它也是用户可访问的功能。 fopen从某种意义上说,比open更高级,因为它返回的FILE*结构为用户封装了内容。有些用户直接使用open来满足特殊需求。因此,以任何方式将fopen称为“系统调用”是不正确的。它也不直接执行系统调用,因为open也是一个可由用户调用的函数。

3

如果你正在使用Linux可以监视应用程序进行系统调用:

strace的应用程序的名字......

它的输出可能给你什么的libc内正在进行一个很好的洞察力,以及函数实际上是系统调用。

6

实际上,系统调用与函数调用无关。这两种机制唯一的共同点就是它们都为调用者提供服务。

  • 从视图线程执行,看看系统调用:

    系统调用是功能的应用模式程序以请求由下划线OS提供的服务。系统调用将使正在运行的线程从用户模式进入内核模式,执行系统调用处理函数,然后返回到用户模式。

  • 系统调用参数:

    系统调用的参数(系统调用号,参数...)。 params的含义和格式取决于系统调用号码。

  • 从视图中提供给用户级程序的系统调用库:

    用户模式程序通常调用的glibc的库调用系统调用。例如,glibc中的open()函数:

    1. 放于EAX SYS_OPEN系统调用号调用软件中断或sys_enter指令
0

系统调用注册

  • 请求的系统调用在kernet级别执行,而不是在用户spce中执行,因为它需要一些特权才能访问硬件。

    因此,在用户空间编程和用C语言编写一些普通函数调用如fopen时,libc通常会将此函数包装到特定的代码中,其中产生中断以从用户空间切换到内核空间,然后在内核空间在硬件级执行函数调用功能所需的系统调用将在内核空间中执行。