用户与内核的交互-用户程序向内核发起交互的方式

1 系统调用

1-1 概念

用户进程在通常情况下不允许访问内核数据,也无法使用内核函数。用户只能在用户空间操作用户数据、调用用户空间函数。比如我们熟悉的“hello world”程序执行时就是标准的用户空间进程,它使用的打印函数printf就属于用户空间函数,打印的字符“hello word”字符串也属于用户空间数据。

但是很多情况下,用户进程需要获得系统服务(调用系统程序),就可以使用系统调用。比如用户想要请求系统打开文件、关闭文件或读写文件,就可以通过文件系统相关的系统调用来做到。用户想要获得系统时间或设置定时器等,就可以通过时钟相关的系统调用来做到。

系统调用是用户级程序访问内核最基本的方法。但在实际C语言开发中我们一般不直接进行系统调用,而是通过一些用户编程接口(API)来调用。

首先讲一下用户编程接口(API)。用户编程接口其实是一些函数定义,比如read()、malloc()、free()、abs()等。这些API主要是通过C库(libc)实现的。我们在调用这些函数时,函数内部实际上是进行的系统调用。比如read()函数就和read系统调用对应;再比如malloc()、free()内部利用brk系统调用来扩大或缩小进程的堆。当然也有一些函数并没有使用系统调用。比如计算整数绝对值的abs()就没有使用系统调用。

Linux有大约两百多个系统调用,可以在很多渠道查阅到它的系统调用表。网上也很容易搜到。

当然,我们除了使用C语言函数来使用系统调用之外,还可以直接使用系统调用。如果你愿意直接调用,Linux内核也提供了一个syscall()函数来实现调用

下面是一个打印进程号的C语言程序,它使用两种方法来打印。第一种是直接使用系统调用,第二种是通过C语言函数调用:

#include <syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(void) {
   
	long ID1, ID2;
	/* 直接系统调用*/
	ID1 = syscall(SYS_getpid);
	printf ("syscall(SYS_getpid)=%ld\n", ID1);
	/* 使用"libc"封装的系统调用 */
	ID2 = getpid();
	printf ("getpid()=%ld\n", ID2);
	return(
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值