最近我正在学习操作系统。我只想知道:
系统调用(如write())和标准库函数(如printf())之间有什么区别?
答案 0 :(得分:49)
系统调用是对函数的调用,该函数不是应用程序的一部分,而是在内核中。内核是一个软件层,为您提供一些基本功能来抽象硬件。粗略地说,内核可以将您的硬件变成软件。
您总是最终使用write()
在外围设备上写任何内容,无论您使用哪种设备。 write()
旨在仅编写一个字节序列,这就是全部,仅此而已。但由于write()
被认为过于基本(您可能希望以十个为基础编写整数,或者以科学计数法编写浮点数等),因此可以通过不同类型的编程环境为您提供不同的库以方便您。
例如,C编程语言为您提供printf()
,允许您以多种不同格式写入数据。因此,您可以将printf()
理解为将数据转换为格式化字节序列的函数,并调用write()
将这些字节写入输出。但是C ++会给你cout
; Java System.out.println
等。这些函数中的每一个都以write()
的调用结束(至少在POSIX系统上)。
有一点需要知道(重要)是这样的系统调用是昂贵的!这不是一个简单的函数调用,因为你需要调用你自己的代码之外的东西,系统必须确保你不要试图做令人讨厌的事情等等。所以它在更高的类似打印功能中是很常见的一些缓冲是内置的;这样写并不总是被调用,但是你的数据被保存在一些隐藏的结构中,只有在真正需要或必要时才会写入(缓冲区已满或你真的想看到打印结果)。
这正是您管理资金时所发生的情况。如果很多人每人给你5块钱,你就不会把它们存入银行!你将它们放在你的钱包上(这是打印)直到它已满或者你不想再保留它们了。然后你去银行存款(这是写)。而且你知道,给钱包5美元要比去银行和存款要快得多。银行是内核/操作系统。
答案 1 :(得分:1)
系统调用由操作系统实现,并以内核模式运行。库函数在用户模式下实现,就像应用程序代码一样。库函数可能会调用系统调用(例如printf
最终调用write
),但这取决于库函数的用途(数学函数通常不需要使用内核)。
答案 2 :(得分:1)
OS中的系统调用用于与OS交互。例如。 Write()可以用于系统或程序中。
虽然标准库功能是特定于程序的,例如。 printf()将打印出来但它只会在GUI /命令行中,并且不会影响系统。
很抱歉无法发表评论,因为我需要50点评论才能发表评论。
编辑:巴马尔有很好的答案答案 3 :(得分:0)
我正在写一个小程序。目前它只是从stdin中读取每一行并将其打印到stdout。我可以在循环中添加一个写入调用,它会在每行的末尾添加几个字符。但是当我使用printf代替时,所有额外的字符都会聚集在一起,而不是出现在每一行上。
似乎使用printf会导致stderr被缓冲。调用printf后添加fflush(stdout);
可修复输出中的差异。
答案 4 :(得分:0)
我想提到另一点,stdio
缓冲区保留在进程的用户空间内存中,而系统调用write
直接将数据传输到内核缓冲区中。这意味着,如果在fork
和write
调用之后printf
进行处理,则刷新可能会使输出受到三次行缓冲和块缓冲的影响,其中两次属于printf
调用,因为stdio
在子节点中复制了fork
缓冲区。
答案 5 :(得分:0)
printf()
是暴露给用户空间以从C库调用函数的API或接口之一。
printf()
实际上使用write()
系统调用。 write()
系统调用实际上负责将数据发送到输出。