C库函数和系统调用的区别

Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions)

fork完后:

(1)有两个返回值,子进程返回0,父进程返回子进程的id

(2)父子进程谁先运行不确定,由调度系统说了算,但是期望子进程先退出,并且父进程在子进程退出时读取子进程的状态

(3)代码区域: 打印与循环的关系,例如父子进程各自++,第一次打印2个,第二次由2变4,一共打印6次

Fopen(标准C库函数提供)——返回值是FILE*

FILE* stdin:  输入    输入设备:键盘    默认打开文件的描述符:0

FILE* stdout:  输出    输出设备:显示器    默认打开文件的描述符:1

FILE* stderror:  错误    输入设备:显示器   默认打开文件的描述符:2

open(系统调用提供)——返回值new file descriptor(fd)、-1、error

fwrite(有缓冲区):由C语言提供缓冲区,默认为行缓冲,遇到换行符就刷新,但是当重定向到文件时,变成全缓冲,就不刷新,直到缓冲区写满。fork前:暂存在于父进程缓冲区中不刷新,fork后:父进程复制到子进程,此时将缓冲区也复制过去。当进程终止时再刷新缓冲区

write(无缓冲区)



1。系统调用

系统调用提供的函数如open, close, read, write, ioctl等,需包含头文件unistd.h。以write为例:其函数原型为 size_t write(int fd, const void *buf, size_t nbytes),其操作对象为文件描述符或文件句柄fd(file descriptor),要想写一个文件,必须先以可写权限用open系统调用打开一个文件,获得所打开文件的fd,例如 fd=open(/"/dev/video/", O_RDWR)。fd是一个整型值,每新打开一个文件,所获得的fd为当前最大fd加1。Linux系统默认分配了3个文件描述符值:0- standard input,1-standard output,2-standard error。系统调用通常用于底层文件访问(low-level file access),例如在驱动程序中对设备文件的直接访问。系统调用是操作系统相关的,因此一般没有跨操作系统的可移植性

系统调用发生在内核空间,因此如果在用户空间的一般应用程序中使用系统调用来进行文件操作,会有用户空间到内核空间切换的开销。事实上,即使在用户空间使用库函数来对文件进行操作,因为文件总是存在于存储介质上,因此不管是读写操作,都是对硬件(存储器)的操作,都必然会引起系统调用。也就是说,库函数对文件的操作实际上是通过系统调用来实现的。例如C库函数fwrite()就是通过write()系统调用来实现的。这样的话,使用库函数也有系统调用的开销,为什么不直接使用系统调用呢?这是因为,读写文件通常是大量的数据(这种大量是相对于底层驱动的系统调用所实现的数据操作单位而言),这时,使用库函数就可以大大减少系统调用的次数。这一结果又缘于缓冲区技术。在用户空间和内核空间,对文件操作都使用了缓冲区,例如用 fwrite写文件,都是先将内容写到用户空间缓冲区,当用户空间缓冲区满或者写操作结束时,才将用户缓冲区的内容写到内核缓冲区,同样的道理,当内核缓冲区满或写结束时才将内核缓冲区内容写到文件对应的硬件媒介。

2。库函数调用

标准C库函数提供的文件操作函数如fopen, fread, fwrite, fclose, fflush, fseek等,需包含头文件stdio.h。以fwrite为例,其函数原型为size_t fwrite(const void *buffer, size_t size, size_t item_num, FILE *pf),其操作对象为文件指针FILE *pf,要想写一个文件,必须先以可写权限用fopen函数打开一个文件,获得所打开文件的FILE结构指针pf,例如pf=fopen(/ "~/proj/filename/", /"w/")。实际上,由于库函数对文件的操作最终是通过系统调用实现的,因此,每打开一个文件所获得的FILE结构指针都有一个内核空间的文件描述符 fd与之对应。同样有相应的预定义的FILE指针:stdin-standard input,stdout-standard output,stderr-standard error。库函数调用通常用于应用程序中对一般文件的访问。库函数调用是系统无关的,因此可移植性好。由于库函数调用是基于C库的,因此也就不可能用于内核空间的驱动程序中对设备的操作。

时间: 2024-11-05 06:21:39

C库函数和系统调用的区别的相关文章

第二篇:库函数和系统调用的区别

前言 这是一对非常容易混淆的概念.对于用户( 应用程序开发者 )来说,并不一定要严格区分其意义.因为在用户看来,它们都是以C函数的形式出现的.但了解二者的区别对我们掌握整个计算机系统有很大帮助. 区别 1. 一部分库函数实现需要使用系统调用( 如 printf 库函数需要调用 write 系统调用 ) 2. 另一部分库函数实现不需要使用系统调用( 如strcpy 库函数不需要使用系统调用因为它不需要使用CPU特权指令 ) 3. 系统调用一定在内核空间执行,而库函数只有其中的系统调用部分执行时才会

Linux 库函数与系统调用的关系与区别

上周总结了<C 标准库的基础 IO>,其实这些功能函数通过「系统调用」也能实现相应功能.这次文章并不是要详细介绍各系统调用接口的使用方法,而是要深入理解「库函数」与「系统」调用之间的关系和区别. 一.系统调用 系统调用,我们可以理解是操作系统为用户提供的一系列操作的接口(API),这些接口提供了对系统硬件设备功能的操作.这么说可能会比较抽象,举个例子,我们最熟悉的 hello world 程序会在屏幕上打印出信息.程序中调用了 printf() 函数,而库函数 printf 本质上是调用了系统

函数库调用和系统调用的区别

函数库调用和系统调用的区别. 操作系统层面上:系统调用是调用操作系统内核的一部分.系统调用,每个操作系统会存在不同. 速度上:系统调用一次需要35微秒.函数库一次调用耗费半微秒. 系统调用大概有70个. 文件描述符和文件指针的区别 将会进行干嘛呢. 文件描述符是一个整型数字.操作系统的系统调用,都需要传递这个值进去. 作者建议,要使用标准的i/o库调用.这样会出现移植性. 文件指针则是一个内存地址,指向了一个数据结构.结构里面保持哪些内容?描述符,可以有很多种描述办法. 用途不同,文件描述符是进

解析库函数调用与系统调用的区别

基于上一篇文章,系统调用的实现原理,计算机系统的各种硬件资源是有限的,而在现代多任务操作系统上的多个进程都需要这些资源,为了更好的管理这些资源,进程是不允许直接访问的,而是在操作系统的控制下访问,因此操作系统是使用这些资源的唯一入口,而这个入口就是操作系统的系统调用,系统调用属于系统内核的一部分,因此运行在内核态的进程可以直接访问这些资源,而用户态的进程如果想要访问需要先通过中断切换为内核态才可以访问. Linux中处理系统调用的方式与中断类似.每个系统调用都有相应的系统调用号作为唯一的标识,内

标准C库函数和系统调用的关系

标准 C 库函数中可以封装系统调用,也可以不封装系统调用,不同的标准 C 库函数可以封装相同的系统调用.标准 C 库属于用户态,而系统调用属于内核态. 标准 C 库中的函数在不同的操作系统环境下都可以使用,比如 fopen 函数在linux下可以使用,在windos下也可以使用.所以说程序的可移植性比较好. 系统调用是依赖于具体操作系统的,比如 read 函数只能在linux下或者满足POSIX标准的操作系统下使用,由于window不满足POSIX标准,所以window下不能使用.可移植性比较差

C++/C语言的标准库函数与运算符的区别new/delete malloc/free

malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符.它们都可用于申请动态内存和释放内存.下面来看他们的区别. 一.操作对象有所不同 malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符.对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求. 对象在创建的同时要自动执行构造函数,对象消亡之前要自动执行析构函数.由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能把执行构造函数

linux 相关库函数与系统调用动态实现

//库函数 void Memset(void *mem, unsigned char byte, unsigned int len); void _memcpy(void *, void *, unsigned int); int _printf(char *, ...); char * itoa(long, char *); char * itox(long, char *); int _puts(char *); int _puts_nl(char *); size_t _strlen(ch

glibc库函数,系统调用API

glibc封装了大部分系统API,我们一般都是使用glibc封装的接口进行系统调用,碰到一些没有封装的接口,可以通过这个 函数syscall 进行系统调用. 1 /* Invoke `system call' number SYSNO, passing it the remaining arguments. 2 This is completely system-dependent, and not often useful. 3 4 In Unix, `syscall' sets `errno

fcntl和flock两个系统调用的区别

总的来说,flock函数只能锁定整个文件,无法锁定文件的某一区域.而fcntl可以利用struct flock结构体,来实现文件里部分区域锁定的操作. 附:fcntl(文件描述词操作) 相关函数 open,flock 表头文件 #include<unistd.h>#include<fcntl.h> 定义函数 int fcntl(int fd , int cmd);int fcntl(int fd,int cmd,long arg);int fcntl(int fd,int cmd,