精华内容
下载资源
问答
  • linux常见系统调用函数列表

    千次阅读 2017-05-11 09:41:18
    以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数。这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很...

    以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数。这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的。

    按照惯例,这个列表以man pages第2节,即系统调用节为蓝本。按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统调用,对个别本人稍觉不妥的地方作了一些小的修改,并对所有列出的系统调用附上简要注释。

    其中有一些函数的作用完全相同,只是参数不同。(可能很多熟悉C++朋友马上就能联想起函数重载,但是别忘了Linux核心是用C语言写的,所以只能取成不同的函数名)。还有一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数我会在前面标上“*”号以示区别。
    一、进程控制:
    fork 创建一个新进程
    clone 按指定条件创建子进程
    execve 运行可执行文件
    exit 中止进程
    _exit 立即中止当前进程
    getdtablesize 进程所能打开的最大文件数
    getpgid 获取指定进程组标识号
    setpgid 设置指定进程组标志号
    getpgrp 获取当前进程组标识号
    setpgrp 设置当前进程组标志号
    getpid 获取进程标识号
    getppid 获取父进程标识号
    getpriority 获取调度优先级
    setpriority 设置调度优先级
    modify_ldt 读写进程的本地描述表
    nanosleep 使进程睡眠指定的时间
    nice 改变分时进程的优先级
    pause 挂起进程,等待信号
    personality 设置进程运行域
    prctl 对进程进行特定操作
    ptrace 进程跟踪
    sched_get_priority_max 取得静态优先级的上限
    sched_get_priority_min 取得静态优先级的下限
    sched_getparam 取得进程的调度参数
    sched_getscheduler 取得指定进程的调度策略
    sched_rr_get_interval 取得按RR算法调度的实时进程的时间片长度
    sched_setparam 设置进程的调度参数
    sched_setscheduler 设置指定进程的调度策略和参数
    sched_yield 进程主动让出处理器,并将自己等候调度队列队尾
    vfork 创建一个子进程,以供执行新程序,常与execve等同时使用
    wait 等待子进程终止
    wait3 参见wait
    waitpid 等待指定子进程终止
    wait4 参见waitpid
    capget 获取进程权限
    capset 设置进程权限
    getsid 获取会晤标识号
    setsid 设置会晤标识号

    回页首
    二、文件系统控制
    1、文件读写操作
    fcntl 文件控制
    open 打开文件
    creat 创建新文件
    close 关闭文件描述字
    read 读文件
    write 写文件
    readv 从文件读入数据到缓冲数组中
    writev 将缓冲数组里的数据写入文件
    pread 对文件随机读
    pwrite 对文件随机写
    lseek 移动文件指针
    _llseek 在64位地址空间里移动文件指针
    dup 复制已打开的文件描述字
    dup2 按指定条件复制文件描述字
    flock 文件加/解锁
    poll I/O多路转换
    truncate 截断文件
    ftruncate 参见truncate
    umask 设置文件权限掩码
    fsync 把文件在内存中的部分写回磁盘

    2、文件系统操作
    access 确定文件的可存取性
    chdir 改变当前工作目录
    fchdir 参见chdir
    chmod 改变文件方式
    fchmod 参见chmod
    chown 改变文件的属主或用户组
    fchown 参见chown
    lchown 参见chown
    chroot 改变根目录
    stat 取文件状态信息
    lstat 参见stat
    fstat 参见stat
    statfs 取文件系统信息
    fstatfs 参见statfs
    readdir 读取目录项
    getdents 读取目录项
    mkdir 创建目录
    mknod 创建索引节点
    rmdir 删除目录
    rename 文件改名
    link 创建链接
    symlink 创建符号链接
    unlink 删除链接
    readlink 读符号链接的值
    mount 安装文件系统
    umount 卸下文件系统
    ustat 取文件系统信息
    utime 改变文件的访问修改时间
    utimes 参见utime
    quotactl 控制磁盘配额

    回页首
    三、系统控制
    ioctl I/O总控制函数
    _sysctl 读/写系统参数
    acct 启用或禁止进程记账
    getrlimit 获取系统资源上限
    setrlimit 设置系统资源上限
    getrusage 获取系统资源使用情况
    uselib 选择要使用的二进制函数库
    ioperm 设置端口I/O权限
    iopl 改变进程I/O权限级别
    outb 低级端口操作
    reboot 重新启动
    swapon 打开交换文件和设备
    swapoff 关闭交换文件和设备
    bdflush 控制bdflush守护进程
    sysfs 取核心支持的文件系统类型
    sysinfo 取得系统信息
    adjtimex 调整系统时钟
    alarm 设置进程的闹钟
    getitimer 获取计时器值
    setitimer 设置计时器值
    gettimeofday 取时间和时区
    settimeofday 设置时间和时区
    stime 设置系统日期和时间
    time 取得系统时间
    times 取进程运行时间
    uname 获取当前UNIX系统的名称、版本和主机等信息
    vhangup 挂起当前终端
    nfsservctl 对NFS守护进程进行控制
    vm86 进入模拟8086模式
    create_module 创建可装载的模块项
    delete_module 删除可装载的模块项
    init_module 初始化模块
    query_module 查询模块信息
    *get_kernel_syms 取得核心符号,已被query_module代替

    回页首
    四、内存管理
    brk 改变数据段空间的分配
    sbrk 参见brk
    mlock 内存页面加锁
    munlock 内存页面解锁
    mlockall 调用进程所有内存页面加锁
    munlockall 调用进程所有内存页面解锁
    mmap 映射虚拟内存页
    munmap 去除内存页映射
    mremap 重新映射虚拟内存地址
    msync 将映射内存中的数据写回磁盘
    mprotect 设置内存映像保护
    getpagesize 获取页面大小
    sync 将内存缓冲区数据写回硬盘
    cacheflush 将指定缓冲区中的内容写回磁盘

    回页首
    五、网络管理
    getdomainname 取域名
    setdomainname 设置域名
    gethostid 获取主机标识号
    sethostid 设置主机标识号
    gethostname 获取本主机名称
    sethostname 设置主机名称

    回页首
    六、socket控制
    socketcall socket系统调用
    socket 建立socket
    bind 绑定socket到端口
    connect 连接远程主机
    accept 响应socket连接请求
    send 通过socket发送信息
    sendto 发送UDP信息
    sendmsg 参见send
    recv 通过socket接收信息
    recvfrom 接收UDP信息
    recvmsg 参见recv
    listen 监听socket端口
    select 对多路同步I/O进行轮询
    shutdown 关闭socket上的连接
    getsockname 取得本地socket名字
    getpeername 获取通信对方的socket名字
    getsockopt 取端口设置
    setsockopt 设置端口参数
    sendfile 在文件或端口间传输数据
    socketpair 创建一对已联接的无名socket

    回页首
    七、用户管理
    getuid 获取用户标识号
    setuid 设置用户标志号
    getgid 获取组标识号
    setgid 设置组标志号
    getegid 获取有效组标识号
    setegid 设置有效组标识号
    geteuid 获取有效用户标识号
    seteuid 设置有效用户标识号
    setregid 分别设置真实和有效的的组标识号
    setreuid 分别设置真实和有效的用户标识号
    getresgid 分别获取真实的,有效的和保存过的组标识号
    setresgid 分别设置真实的,有效的和保存过的组标识号
    getresuid 分别获取真实的,有效的和保存过的用户标识号
    setresuid 分别设置真实的,有效的和保存过的用户标识号
    setfsgid 设置文件系统检查时使用的组标识号
    setfsuid 设置文件系统检查时使用的用户标识号
    getgroups 获取后补组标志清单
    setgroups 设置后补组标志清单

    回页首
    八、进程间通信
    ipc 进程间通信总控制调用

    1、信号
    sigaction 设置对指定信号的处理方法
    sigprocmask 根据参数对信号集中的信号执行阻塞/解除阻塞等操作
    sigpending 为指定的被阻塞信号设置队列
    sigsuspend 挂起进程等待特定信号
    signal 参见signal
    kill 向进程或进程组发信号
    *sigblock 向被阻塞信号掩码中添加信号,已被sigprocmask代替
    *siggetmask 取得现有阻塞信号掩码,已被sigprocmask代替
    *sigsetmask 用给定信号掩码替换现有阻塞信号掩码,已被sigprocmask代替
    *sigmask 将给定的信号转化为掩码,已被sigprocmask代替
    *sigpause 作用同sigsuspend,已被sigsuspend代替
    sigvec 为兼容BSD而设的信号处理函数,作用类似sigaction
    ssetmask ANSI C的信号处理函数,作用类似sigaction

    2、消息
    msgctl 消息控制操作
    msgget 获取消息队列
    msgsnd 发消息
    msgrcv 取消息

    3、管道
    pipe 创建管道

    4、信号量
    semctl 信号量控制
    semget 获取一组信号量
    semop 信号量操作

    5、共享内存
    shmctl 控制共享内存
    shmget 获取共享内存
    shmat 连接共享内存
    shmdt 拆卸共享内存

    原文https://www.ibm.com/developerworks/cn/linux/kernel/syscall/part1/appendix.html

    展开全文
  • 系统调用

    千次阅读 多人点赞 2019-03-02 17:47:48
    程序接口通常是由各种类型的系统调用所组成的,因而,也可以说,系统调用提供了用户程序和操作系统之间的接口,应用程序通过系统调用实现其与 OS 的通信,并可取得它的服务。 处理器(CPU)=运算器+控制器+...

    程序接口是 OS 专门为用户程序设置的,也是用户程序取得 OS 服务的唯一途径。程序接口通常是由各种类型的系统调用所组成的,因而,也可以说,系统调用提供了用户程序和操作系统之间的接口,应用程序通过系统调用实现其与 OS 的通信,并可取得它的服务

     

    处理器(CPU)=运算器+控制器+寄存器+高速缓存

     

    系统调用的基本概念


    通常,在 OS 的核心中都设置了一组用于实现各种系统功能的子程序(过程),并将它们提供给应用程序调用。

     


    系统态和用户态


    在计算机系统中,通常运行着两类程序:系统程序和应用程序,为了保证系统程序不被应用程序有意或无意地破坏,为计算机设置了两种状态:

    • 系统态(也称为管态或核心态),操作系统在系统态运行
    • 用户态(也称为目态),应用程序只能在用户态运行。

    在实际运行过程中,处理机会在系统态和用户态间切换。相应地,现代多数操作系统将 CPU 的指令集分为特权指令和非特权指令两类。


    1) 特权指令——在系统态时运行的指令

    • 对内存空间的访问范围基本不受限制,不仅能访问用户存储空间,也能访问系统存储空间,
    • 特权指令只允许操作系统使用,不允许应用程序使用,否则会引起系统混乱。

     

    2) 非特权指令——在用户态时运行的指令

    一般应用程序所使用的都是非特权指令,它只能完成一般性的操作和任务,不能对系统中的硬件和软件直接进行访问,其对内存的访问范围也局限于用户空间。

     

     

    系统调用

     

    如上所述,一方面由于系统提供了保护机制,防止应用程序直接调用操作系统的过程,从而避免了系统的不安全性。但另一方面,应用程序又必须取得操作系统所提供的服务,否则,应用程序几乎无法作任何有价值的事情,甚至无法运行。为此,在操作系统中提供了系统调用,使应用程序可以通过系统调用的方法,间接调用操作系统的相关过程,取得相应的服务

    当应用程序中需要操作系统提供服务时,如请求 I/O 资源或执行 I/O 操作,应用程序必须使用系统调用命令。由操作系统捕获到该命令后,便将 CPU 的状态从用户态转换到系统态,然后执行操作系统中相应的子程序(例程),完成所需的功能。执行完成后,系统又将CPU 状态从系统态转换到用户态,再继续执行应用程序。

     

    系统调用和一般调用的区别:

    (1) 运行在不同的系统状态——调用程序是运行在用户态,而被调用程序是运行在系统态。

    (2) 状态的转换通过软中断进入

    • 一般的过程调用并不涉及到系统状态的转换,可直接由调用过程转向被调用过程。
    • 系统调用不允许由调用过程直接转向被调用过程。

    通常都是通过软中断机制,先由用户态转换为系统态,经核心分析后,才能转向相应的系统调用处理子程序。

    (3) 返回问题。

    在采用了抢占式(剥夺)调度方式的系统中,在被调用过程执行完后,要对系统中所有要求运行的进程做优先权分析。当调用进程仍具有最高优先级时,才返回到调用进程继续执行;否则,将引起重新调度,以便让优先权最高的进程优先执行。此时,将把调用进程放入就绪队列。

    (4) 嵌套调用。

    像一般过程一样,系统调用也可以嵌套进行,即在一个被调用过程的执行期间,还可以利用系统调用命令去调用另一个系统调用。当然,每个系统对嵌套调用的深度都有一定的限制,例如最大深度为 6。


    中断机制


    系统调用是通过中断机制实现的,并且一个操作系统的所有系统调用都通过同一个中断入口来实现。对于拥有保护机制的操作系统来说,中断机制本身也是受保护的,

     

     


    系统调用的类型


    对于一般通用的 OS 而言,可将其所提供的系统调用分为:进程控制、文件操纵、通信管理和系统维护等几大类。

     


    进程控制类系统调用


    这类系统调用主要用于对进程的控制,如创建一个新的进程和终止一个进程的运行,获得和设置进程属性等。


    1) 创建和终止进程的系统调用
    在多道程序环境下,为使多道程序能并发执行,必须先利用创建进程的系统调用来为欲参加并发执行的各程序分别创建一个进程。当进程已经执行结束时、 或因发生异常情况而不能继续执行时,可利用终止进程的系统调用来结束该进程的运行。

     

    2) 获得和设置进程属性的系统调用
    当我们创建了一个(些)新进程后,为了能控制它(们)的运行,应当能了解、 确定和重新设置它(们)的属性。这些属性包括: 进程标识符、进程优先级、最大允许执行时间等。此时,我们可利用获得进程属性的系统调用,来了解某进程的属性,利用设置进程属性的系统调用,来确定和重新设置进程的属性。


    3) 等待某事件出现的系统调用
    进程在运行过程中,有时需要等待某事件(条件)出现后方可继续执行。例如,一进程在创建了一个(些)新进程后,需要等待它(们)运行结束后,才能继续执行,此时可利用等待子进程结束的系统调用进行等待;

     


    文件操纵类系统调用


    对文件进行操纵的系统调用数量较多,有创建文件、删除文件、打开文件、关闭文件、读文件、写文件、建立目录、移动文件的读/写指针、改变文件的属性等。


    1) 创建和删除文件
    当用户需要在系统中存放程序或数据时,可利用创建文件的系统调用 creat,由系统根据用户提供的文件名和存取方式来创建一个新文件;当用户已不再需要某文件时,可利用删除文件的系统调用 unlink 将指名文件删除。


    2) 打开和关闭文件
    用户在第一次访问某个文件之前,应先利用打开文件的系统调用 open,将指名文件打开,即系统将在用户(程序)与该文件之间建立一条快捷通路。在文件被打开后,系统将给用户返回一个该文件的句柄或描述符;当用户不再访问某文件时,又可利用关闭文件的系统调用 close,将此文件关闭,即断开该用户程序与该文件之间的快捷通路。


    3) 读和写文件
    用户可利用读系统调用 read,从已打开的文件中读出给定数目的字符,并送至指定的缓冲区中;同样,用户也可利用写系统调用 write,从指定的缓冲区中将给定数目的字符写入指定文件中。read 和 write 两个系统调用是文件操纵类系统调用中使用最频繁的。

     


    进程通信类系统调用


    在 OS 中经常采用两种进程通信方式,即消息传递方式和共享存储区方式。

    当系统中采用消息传递方式时

    1. 先打开一个连接(由源进程发出一条打开连接的系统调用 open connection,目标进程则应利用接受连接的系统调用 accept connection
    2. 可以利用发送消息的系统调用 send message 或者用接收消息的系统调用 receive message 来交换信息。
    3. 通信结束后,还须再利用关闭连接的系统调用 close connection 结束通信。

    用户在利用共享存储区进行通信

    1. 先利用建立共享存储区的系统调用来建立一个共享存储区
    2. 再利用建立连接的系统调用将该共享存储区连接到进程自身的虚地址空间上
    3. 然后便可利用读和写共享存储区的系统调用实现相互通信。

    除上述的三类外,常用的系统调用还包括设备管理类系统调用和信息维护类系统调用,

     

     


    系统调用的实现

     

    系统调用的实现与一般过程调用的实现相比,两者间有很大差异。对于系统调用,控制是由原来的用户态转换为系统态,这是借助于中断和陷入机制来完成的,在该机制中包括中断和陷入硬件机构中断与陷入处理程序两部分。当应用程序使用 OS 的系统调用时,产生一条相应的指令,CPU 在执行这条指令时发生中断,并将有关信号送给中断和陷入硬件机构,该机构收到信号后,启动相关的中断与陷入处理程序进行处理,实现该系统调用所需要的功能。

     

    中断和陷入硬件机构

    1) 中断和陷入的概念(面试考点——中断与异常的区别)

    中断是指 CPU 对系统发生某事件时的这样一种响应: CPU 暂停正在执行的程序,在保留现场后自动地转去执行该事件的中断处理程序;执行完后,再返回到原程序的断点处继续执行。

    下图 表示中断时 CPU 的活动轨迹。还可进一步把中断分为外中断内中断

    • 外中断——是指由于外部设备事件所引起的中断,如通常的磁盘中断、打印机中断等;
    • 内中断——是指由于 CPU 内部事件所引起的中断,如程序出错(非法指令、地址越界)。内中断(trap)也被译为“捕获”或“陷入”。

    通常,陷入是由于执行了现行指令所引起的;而中断则是由于系统中某事件引起的,该事件与现行指令无关。由于系统调用引起的中断属于内中断,因此把由于系统调用引起中断的指令称为陷入指令。

     

    2) 中断和陷入向量(百度面试考过中断向量)
     

    • 针对不同的设备编制不同的中断处理程序,并把该程序的入口地址放在某特定的内存单元中。
    • 不同的设备也对应着不同的处理机状态字PSW,且把它放在与中断处理程序入口指针相邻接的特定单元中。

    在进行中断处理时,只要有了这样两个字,便可转入相应设备的中断处理程序,重新装配处理机的状态字和优先级,进行对该设备的处理。因此,我们把这两个字称为中断向量。相应地,把存放这两个字的单元称为中断向量单元

    类似地,对于陷入,也有陷入向量,不同的系统调用对应不同的陷入向量,在进行陷入处理时,根据陷入指令中的陷入向量,转入实现相应的系统调用功能的子程序,即陷入处理程序。由所有的中断向量和陷入向量构成了中断和陷入向量表,如图所示。

     

     

     

     


    UNIX 系统调用

     

     UNIX 系统调用的类型


    进程控制


    该类系统调用包括:创建进程的系统调用 fork、终止进程的系统调用 exit、等待子进程结束的系统调用 wait 等十多条。


    (1) 创建进程(fork)。

    一个进程可以利用 fork 系统调用来创建一个新进程。新进程是作为调用者的子进程,它继承了其父进程的环境、 已打开的所有文件、根目录和当前目录等,即它继承了父进程几乎所有的属性,并具有与其父进程基本上相同的进程映像。


    (2) 终止进程(exit)。

    一个进程可以利用 exit 实现自我终止。通常,在父进程创建子进程时,便在子进程的末尾安排一条 exit 系统调用。这样,子进程在完成规定的任务后,便可进行自我终止。子进程终止后,留下一记账信息 status,其中包含了子进程运行时记录下来的各种统计信息。


    (3) 等待子进程结束(wait)。

    wait 用于将调用者进程自身挂起,直至它的某一子进程终止为止。这样,父进程可以利用 wait 使自身的执行与子进程的终止同步。


    (4) 执行一个文件(exec)。

    exec 可使调用者进程的进程映像(包括用户程序和数据等)被一个可执行的文件覆盖,此即改变调用者进程的进程映像。该系统调用是 UNIX 系统中最复杂的系统调用之一。


    (5) 获得进程 ID。

    UNIX 系统提供了一组用于获得进程标识符的系统调用,比如,可利用 getpid 系统调用来获得调用进程的标识符,利用 getpgrp 系统调用来获得调用进程的进程组 ID,以及利用 getppid 系统调用来获得调用进程的父进程 ID 等。


    (6) 获得用户 ID。

    UNIX 系统提供了一组用于获得用户 ID 的系统调用,如 getuid 可用于获得真正的用户 ID,geteuid 用于获得有效用户 ID,getgid 用于获得真正用户组 ID 等。


    (7) 进程暂停(pause)。

    可用此系统调用将调用进程挂起,直至它收到一个信号为止。

     

     

    文件操纵


    用于对文件进行操纵的系统调用是数量最多的一类系统调用,其中包括创建文件、打开文件、关闭文件、读文件及写文件等二十多条。


    (1) 创建文件(creat)。

    系统调用 creat 的功能是根据用户提供的文件名和许可权方式,来创建一个新文件或重写一个已存文件。如果系统中不存在指名文件,核心便以给定的文件名和许可权方式来创建一个新文件;如果系统中已有同名文件,核心便释放其已有的数据块。创建后的文件随即被打开,并返回其文件描述符 fd。若 creat 执行失败,便返回“-1”。


    (2) 打开文件(open)。

    open 的功能是把有关的文件属性从磁盘拷贝到内存中,以及在用户和指名文件之间建立一条快捷的通路,并给用户返回一个文件描述符 fd。文件被打开后,用户对文件的任何操作都只须使用 fd 而非路径名。

     

    (3) 关闭文件(close)。

    在 UNIX 系统中,由于允许一个文件被多个进程所共享,故只有在无其他任何进程需要此文件时,才能真正关闭该文件


    (4) 读和写文件 read 和 write。

    仅当用户利用 open 打开指定文件后,方可调用 read 或write 对文件执行读或写操作。两个系统调用都要求用户提供三个输入参数:

    • ① 文件描述符fd。
    • ② buf 缓冲区首址。对读而言,这是用户所要求的信息传送的目标地址;对写而言,这则是信息传送的源地址。
    • ③ 用户要求传送的字节数 n byte。

    系统调用 read 的功能是试图从 fd 所指示的文件中去读入 n byte 个字节的数据,并将它们送至由指针 buf 所指示的缓冲区中;系统调用 write 的功能是试图把 n byte 个字节数据,从指针 buf 所指示的缓冲区中写到由 fd 所指向的文件中。


    (5) 连接和去连接(link 和 unlink)。

    为了实现文件共享,必须记住所有共享该文件的用户数目。为此,在该文件的索引结点中设置了一个连接计数 link。每当有一用户要共享某文件时,须利用系统调用 link 来建立该用户(进程)与此文件之间的连接,并对 i.link 做加 1操作。当用户不再使用此文件时,应利用系统调用 unlink 去断开此连接,亦即做 i.link 的减1 操作。当 i.link 减 1 后结果为 0 时,表示已无用户需要此文件,此时才能将该文件从文件系统中删除。故在 UNIX 系统中并无一条删除文件的系统调用。

     

     

    进程间的通信


    为了实现进程间的通信,在 UNIX 系统中提供了一个用于进程间通信的软件包,简称IPC。它由消息机制、共享存储器机制和信号量机制三部分组成。在每一种通信机制中,都提供了相应的系统调用供用户程序进行进程间的同步与通信之用。

    (1) 消息机制。

    用户(进程)在利用消息机制进行通信时,必须先利用 msgget 系统调用来建立一个消息队列。若成功,便返回消息队列描述符 msgid,以后用户便可利用 msgid 去访问该消息队列。用户(进程)可利用发送消息的系统调用 msgsend 向用户指定的消息队列发送消息;利用 msgrcv 系统调用从指定的消息队列中接收指定类型的消息。

    (2) 共享存储器机制。

    当用户(进程)要利用共享存储器机制进行通信时,必须先利用shmget 系统调用来建立一个共享存储区,若成功,便返回该共享存储区描述符 shmid。以后,用户便可利用 shmid 去访问该共享存储区。进程在建立了共享存储区之后,还必须再利用shmat 将该共享存储区连接到本进程的虚地址空间上。以后,在进程之间便可利用该共享存储区进行通信。当进程不再需要该共享存储区时,可利用 shmdt 系统调用来拆除进程与共享存储区间的连接。

    (3) 信号量机制。

    在 UNIX 系统中所采用的信号量机制,允许将一组信号量形成一个信号量集,并对这组信号量施以原子操作

     

     

    信息维护

     

    在 UNIX 系统中,设置了许多条用于系统维护的系统调用。


    (1) 设置和获得时间。

    超级用户可利用设置时间的系统调用(stime),来设置系统的日期和时间。如果调用进程并非超级用户,则 stime 失败。一般用户可利用获得时间的系统调用time 来获得当前的日期和时间。

    (2) 获得进程和子进程时间(times)。

    利用该系统调用可获得进程及其子进程所使用的CPU 时间,其中包括调用进程在用户空间执行指令所花费的时间,系统为调用进程所花费的 CPU 时间、子进程在用户空间所用的 CPU 时间、系统为各子进程所花费的 CPU 时间等,并可将这些时间填写到一个指定的缓冲区。

    (3) 设置文件访问和修改时间(utime)。

    该系统调用用于设置指名文件被访问和修改的时间。如果该系统调用的参数 times 为 NULL 时,文件主和对该文件具有写权限的用户,可将对该文件的访问和修改时间设置为当前时间;如果 times 不为 NULL,则把 times 解释为指向 utim buf 结构的指针,此时,文件主和超级用户能将访问时间和修改时间置入 utim buf结构中。

    (4) 获得当前 UNIX 系统的名称(uname)。

    利用该系统调用可将有关 UNIX 系统的信息存储在 utsname 结构中。 这些信息包括 UNIX 系统名称的字符串、系统在网络中的名称、 硬件的标准名称等。

     

     

    展开全文
  • 【Linux系统编程】Linux系统调用

    千次阅读 多人点赞 2019-09-22 20:52:34
    用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。 ...

    00. 目录

    01. 系统调用概述

    系统调用顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。

    从逻辑上来说,系统调用可被看成是一个内核与用户空间程序交互的接口——它好比一个中间人,把用户进程的请求传达给内核,待内核把请求处理完毕后再将处理结果送回给用户空间。
    在这里插入图片描述

    系统服务之所以需要通过系统调用来提供给用户空间的根本原因是为了对系统进行“保护”,因为我们知道 Linux 的运行空间分为内核空间用户空间,它们各自运行在不同的级别中,逻辑上相互隔离。所以用户进程在通常情况下不允许访问内核数据,也无法使用内核函数,它们只能在用户空间操作用户数据,调用用户空间函数。比如我们熟悉的“hello world”程序(执行时)就是标准的用户空间进程,它使用的打印函数 printf 就属于用户空间函数,打印的字符“hello word”字符串也属于用户空间数据。

    但是很多情况下,用户进程需要获得系统服务(调用系统程序),这时就必须利用系统提供给用户的“特殊接口”——系统调用了,它的特殊性主要在于规定了用户进程进入内核的具体位置;换句话说,用户访问内核的路径是事先规定好的,只能从规定位置进入内核,而不准许肆意跳入内核。有了这样的陷入内核的统一访问路径限制才能保证内核安全无误。我们可以形象地描述这种机制:作为一个游客,你可以买票要求进入野生动物园,但你必须老老实实地坐在观光车上,按照规定的路线观光游览。当然,不准下车,因为那样太危险,不是让你丢掉小命,就是让你吓坏了野生动物。

    02. 系统调用实现

    系统调用是属于操作系统内核的一部分的,必须以某种方式提供给进程让它们去调用。CPU 可以在不同的特权级别下运行,而相应的操作系统也有不同的运行级别,用户态和内核态。运行在内核态的进程可以毫无限制的访问各种资源,而在用户态下的用户进程的各种操作都有着限制,比如不能随意的访问内存、不能开闭中断以及切换运行的特权级别。显然,属于内核的系统调用一定是运行在内核态下,但是如何切换到内核态呢?

    答案是软件中断。软件中断和我们常说的中断(硬件中断)不同之处在于,它是通过软件指令触发而并非外设引发的中断,也就是说,又是编程人员开发出的一种异常(该异常为正常的异常)。操作系统一般是通过软件中断从用户态切换到内核态。

    中断有两个重要的属性,中断号和中断处理程序。中断号用来标识不同的中断,不同的中断具有不同的中断处理程序。在操作系统内核中维护着一个中断向量表(Interrupt Vector Table),这个数组存储了所有中断处理程序的地址,而中断号就是相应中断在中断向量表中的偏移量。更多详细说明请看《系统调用的实现原理》。

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

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

    库函数由两类函数组成:

    1) 不需要调用系统调用

    不需要切换到内核空间即可完成函数全部功能,并且将结果反馈给应用程序,如strcpy、bzero 等字符串操作函数。

    2)需要调用系统调用

    需要切换到内核空间,这类函数通过封装系统调用去实现相应功能,如 printf、fread等。

    在这里插入图片描述

    系统调用是需要时间的,程序中频繁的使用系统调用会降低程序的运行效率。当运行内核代码时,CPU工作在内核态,在系统调用发生前需要保存用户态的栈和内存环境,然后转入内核态工作。系统调用结束后,又要切换回用户态。这种环境的切换会消耗掉许多时间。

    库函数访问文件的时候根据需要,设置不同类型的缓冲区,从而减少了直接调用 IO 系统调用的次数,提高了访问效率。缓冲区详情请看《浅谈标准I/O缓冲区》。

    这个过程类似于快递员给某个区域(内核空间)送快递一样,快递员有两种方式送:

    1. 来一件快递就马上送到目的地,来一件送一件,这样导致来回走比较频繁(系统调用

    2. 等快递攒着差不多后(缓冲区),才一次性送到目的地(库函数调用

    04. 附录

    参考:【Linux】一步一步学Linux系统编程教程汇总

    展开全文
  • Linux系统调用

    千次阅读 2018-03-19 13:19:45
    1 概述相比Intel支持的快速系统调用指令sysenter/sysexit,AMD对应的是syscall/sysret,不过现在,Intel也兼容这两条指令。 测试环境:Ubuntu 12.04Ubuntu 16.04 642 传统系统调用int 0x80只用于32位系统,64位...

    概述

    相比Intel支持的快速系统调用指令sysenter/sysexit,AMD对应的是syscall/sysret,不过现在,Intel也兼容这两条指令

     

    测试环境:

    Ubuntu 12.04

    Ubuntu 16.04 64

    传统系统调用int 0x80

    只用于32位系统,64位系统上不起作用;

     系统调用号和返回结果

    EAX指定要调用的函数(系统调用号)

    EBX传递函数的第一个参数

    ECX传递函数的第二个参数

    EDX传递函数的第三个参数

    返回值EAX

     示例

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/syscall.h>

    #define STRINGFY_(x) #x
    #define STRINGFY(x) STRINGFY_(x)

    int main()
    {
    pid_t pid;

    asm volatile("movl $"STRINGFY(__NR_getpid)", %%eax\n"
    "int $0x80\n"
    : "=a"(pid));
    printf("pid=%u\n", pid);

    return 0;
    }

    32位系统调用sysenter

    3.1 系统调用

    系统调用号:

    sys/syscall.h

    /usr/include/i386-linux-gnu/asm/unistd_32.h

    如:

    #define __NR_getuid              24

    #define __NR_getuid32           199

    参数:

    EAX指定要调用的函数(系统调用号)

    EBX传递函数的第一个参数

    ECX传递函数的第二个参数

    EDX传递函数的第三个参数

    ESI

    EDI

    EBP

    返回值EAX

     

    静态链接时,采用"call *_dl_sysinfo"指令;

    动态链接时,采用"call *%gs:0x10"指令;

    最终调用的是VDSO(linux-gate.so.1)中的__kernel_vsyscall函数;

    __kernel_vsyscall函数包含sysenter指令;

     

    syscall()函数也是类似的,根据静态/动态链接的不同分别采用的不同的指令,最终调用__kernel_vsyscall函数;

    3.2 静态链接实例

    millionsky@ubuntu-12:~/tmp$ gcc getuid_glibc.c -static

    millionsky@ubuntu-12:~/tmp$ gdb ./a.out

    (gdb) b main

    Breakpoint 1 at 0x8048ee3

    (gdb) r

    Starting program: /home/millionsky/tmp/a.out

     

    Breakpoint 1, 0x08048ee3 in main ()

    (gdb) disass

    Dump of assembler code for function main:

       0x08048ee0 <+0>:     push   %ebp

       0x08048ee1 <+1>:     mov    %esp,%ebp

    => 0x08048ee3 <+3>:     and    $0xfffffff0,%esp

       0x08048ee6 <+6>:     sub    $0x10,%esp

       0x08048ee9 <+9>:     call   0x8053c00 <getuid>

       0x08048eee <+14>:    mov    $0x80c6088,%edx

       0x08048ef3 <+19>:    mov    %eax,0x4(%esp)

       0x08048ef7 <+23>:    mov    %edx,(%esp)

       0x08048efa <+26>:    call   0x8049980 <printf>

       0x08048eff <+31>:    mov    $0x0,%eax

       0x08048f04 <+36>:    leave  

       0x08048f05 <+37>:    ret    

    End of assembler dump.

    (gdb) disass 0x8053c00

    Dump of assembler code for function getuid:

       0x08053c00 <+0>:     mov    $0xc7,%eax  //__NR_getuid32

       0x08053c05 <+5>:     call   *0x80ef5a4

       0x08053c0b <+11>:    ret    

    End of assembler dump.

    (gdb) x 0x80ef5a4

    0x80ef5a4 <_dl_sysinfo>:        0xb7fff414

    (gdb) disass 0xb7fff414

    Dump of assembler code for function __kernel_vsyscall:

       0xb7fff414 <+0>:     push   %ecx

       0xb7fff415 <+1>:     push   %edx

       0xb7fff416 <+2>:     push   %ebp

       0xb7fff417 <+3>:     mov    %esp,%ebp

       0xb7fff419 <+5>:     sysenter

       0xb7fff41b <+7>:     nop

       0xb7fff41c <+8>:     nop

       0xb7fff41d <+9>:     nop

       0xb7fff41e <+10>:    nop

       0xb7fff41f <+11>:    nop

       0xb7fff420 <+12>:    nop

       0xb7fff421 <+13>:    nop

       0xb7fff422 <+14>:    int    $0x80

       0xb7fff424 <+16>:    pop    %ebp

       0xb7fff425 <+17>:    pop    %edx

       0xb7fff426 <+18>:    pop    %ecx

       0xb7fff427 <+19>:    ret    

    End of assembler dump.

    3.3 动态链接实例

    millionsky@ubuntu-12:~/tmp$ gcc getuid_glibc.c

    millionsky@ubuntu-12:~/tmp$ gdb ./a.out

    (gdb) b main

    Breakpoint 1 at 0x8048417

    (gdb) r

    Starting program: /home/millionsky/tmp/a.out

     

    Breakpoint 1, 0x08048417 in main ()

    (gdb) b getuid

    Breakpoint 2 at 0xb7ed9c30

    (gdb) c

    Continuing.

     

    Breakpoint 2, 0xb7ed9c30 in getuid () from /lib/i386-linux-gnu/libc.so.6

    (gdb) disass

    Dump of assembler code for function getuid:

    => 0xb7ed9c30 <+0>:     mov    $0xc7,%eax

       0xb7ed9c35 <+5>:     call   *%gs:0x10

       0xb7ed9c3c <+12>:    ret    

    End of assembler dump.

    (gdb) si

    0xb7ed9c35 in getuid () from /lib/i386-linux-gnu/libc.so.6

    (gdb)

    0xb7fdd414 in __kernel_vsyscall ()

    (gdb) disass

    Dump of assembler code for function __kernel_vsyscall:

    => 0xb7fdd414 <+0>:     push   %ecx

       0xb7fdd415 <+1>:     push   %edx

       0xb7fdd416 <+2>:     push   %ebp

       0xb7fdd417 <+3>:     mov    %esp,%ebp

       0xb7fdd419 <+5>:     sysenter

       0xb7fdd41b <+7>:     nop

       0xb7fdd41c <+8>:     nop

       0xb7fdd41d <+9>:     nop

       0xb7fdd41e <+10>:    nop

       0xb7fdd41f <+11>:    nop

       0xb7fdd420 <+12>:    nop

       0xb7fdd421 <+13>:    nop

       0xb7fdd422 <+14>:    int    $0x80

       0xb7fdd424 <+16>:    pop    %ebp

       0xb7fdd425 <+17>:    pop    %edx

       0xb7fdd426 <+18>:    pop    %ecx

       0xb7fdd427 <+19>:    ret    

    End of assembler dump.

    3.4 汇编使用

    3.4.1 模拟__kernel_vsyscall

    直接执行sysenter指令,执行完成后,内核sysexit会跳转到__kernel_vsyscall的后半部分继续执行:

    Dump of assembler code for function __kernel_vsyscall:

       0xb7fff414 <+0>:     push   %ecx

       0xb7fff415 <+1>:     push   %edx

       0xb7fff416 <+2>:     push   %ebp

       0xb7fff417 <+3>:     mov    %esp,%ebp

       0xb7fff419 <+5>:     sysenter

       0xb7fff41b <+7>:     nop

       0xb7fff41c <+8>:     nop

       0xb7fff41d <+9>:     nop

       0xb7fff41e <+10>:    nop

       0xb7fff41f <+11>:    nop

       0xb7fff420 <+12>:    nop

       0xb7fff421 <+13>:    nop

       0xb7fff422 <+14>:    int    $0x80

       0xb7fff424 <+16>:    pop    %ebp     //跳转到这里

       0xb7fff425 <+17>:    pop    %edx

       0xb7fff426 <+18>:    pop    %ecx

       0xb7fff427 <+19>:    ret    

    因此需要注意以下几点:

    保存返回地址(sysenter指令的下一条指令)

    保存ecx、edx寄存器(sysexit指令需要使用这两个寄存器);

    asm("push %ecx\n");

    asm("push %edx\n");

    增加函数头

    asm("push %ebp\n");

    asm("mov %esp,%ebp\n"); 

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/syscall.h>

    #define STRINGFY_(x) #x
    #define STRINGFY(x) STRINGFY_(x)

    int main()
    {
    pid_t pid;

    //simulate __kernel_vsyscall
        asm("jmp label2\n");
        asm("label1:\n");

        asm("push %ecx\n");
        asm("push %edx\n");
        asm("push %ebp\n");
        asm("mov %esp,%ebp\n");

        asm("movl $"STRINGFY(__NR_getpid)", %eax\n");
        asm("sysenter\n");
        asm("label2:");
    asm("call label1\n");
        asm("": "=a"(pid));
        printf("pid=%u\n", pid);

    return 0;
    }

     

    3.4.2调用__kernel_vsyscall

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/syscall.h>

    #define STRINGFY_(x) #x
    #define STRINGFY(x) STRINGFY_(x)

    int main()
    {
    pid_t pid;

    asm("movl $"STRINGFY(__NR_getpid)", %eax\n");
    asm("call *%gs:0x10\n");
    asm("": "=a"(pid));
    printf("pid=%u\n", pid);

    return 0;
    }


    64位系统调用syscall

    4.1 系统调用

    系统调用号:

    sys/syscall.h

    /usr/include/x86_64-linux-gnu/asm/unistd_64.h

     

    参数(man syscall):

     

     

    参数寄存器:

     

    静态链接时,直接调用syscall指令;

    动态链接时,调用libc的系统调用代码,调用syscall指令;

    syscall()函数也是类似的,最终调用syscall指令;

    4.2 静态链接实例

    millionsky@ubuntu-16:~/tmp/VDSO$ cat getuid_glibc.c

    /**

     * filename: getuid_glibc.c

     */

    #include <stdio.h>

    #include <unistd.h>

    #include <sys/types.h>

     

    int main(int argc, char *argv[])

    {

        printf("uid:%d\n", getuid());

        return 0;

    }

    millionsky@ubuntu-16:~/tmp/VDSO$ gcc getuid_glibc.c -o getuid_glibc -static

     

    GDB调试

    millionsky@ubuntu-16:~/tmp/VDSO$ gdb ./getuid_glibc -q

    Reading symbols from ./getuid_glibc...(no debugging symbols found)...done.

    (gdb) tb __getuid

    Temporary breakpoint 1 at 0x43e8e0

    (gdb) r

    Starting program: /home/millionsky/tmp/VDSO/getuid_glibc

     

    Temporary breakpoint 1, 0x000000000043e8e0 in getuid ()

    (gdb) disass

    Dump of assembler code for function getuid:

    => 0x000000000043e8e0 <+0>:  mov    $0x66,%eax

       0x000000000043e8e5 <+5>:  syscall

       0x000000000043e8e7 <+7>:  retq   

    End of assembler dump.

    值0x66是__NR_getuid在x64上的值,即把__NR_getuid放到eax寄存器后,不再是执行指令int 0x80,而是执行指令syscall。

    4.3 动态链接实例

    millionsky@ubuntu-16:~/tmp/SROP$ gcc getuid_glibc.c

    millionsky@ubuntu-16:~/tmp/SROP$ gdb ./a.out

    (gdb) b main

    Breakpoint 1 at 0x40056a

    (gdb) r

    Starting program: /home/millionsky/tmp/SROP/a.out

     

    Breakpoint 1, 0x000000000040056a in main ()

    (gdb) b __getuid

    Breakpoint 2 at 0x7ffff7ada240: file ../sysdeps/unix/syscall-template.S, line 65.

    (gdb) c

    Continuing.

     

    Breakpoint 2, getuid () at ../sysdeps/unix/syscall-template.S:65

    65      ../sysdeps/unix/syscall-template.S: 没有那个文件或目录.

    (gdb) disass

    Dump of assembler code for function getuid:

    => 0x00007ffff7ada240 <+0>:     mov    $0x66,%eax

       0x00007ffff7ada245 <+5>:     syscall

       0x00007ffff7ada247 <+7>:     retq   

    End of assembler dump.

     

    4.4 syscall函数实例

    millionsky@ubuntu-16:~/tmp/VDSO$ cat getuid_syscall.c

     /**

      * filename: getuid_syscall.c

      */

    #include <stdio.h>

    #define _GNU_SOURCE

    #include <unistd.h>

    #include <sys/syscall.h>

     

    int main(int argc, char *argv[])

    {

        printf("uid:%ld\n", syscall(__NR_getuid));

        return 0;

    }

    millionsky@ubuntu-16:~/tmp/VDSO$ gcc getuid_syscall.c -o getuid_syscall -static

     

    GDB调试

    millionsky@ubuntu-16:~/tmp/VDSO$ gdb ./getuid_syscall -q

    Reading symbols from ./getuid_syscall...(no debugging symbols found)...done.

    (gdb) b main

    Breakpoint 1 at 0x4009b2

    (gdb) r

    Starting program: /home/millionsky/tmp/VDSO/getuid_syscall

     

    Breakpoint 1, 0x00000000004009b2 in main ()

    (gdb) disass

    Dump of assembler code for function main:

       ...

     0x00000000004009bd <+15>: mov    $0x66,%edi

       0x00000000004009c2 <+20>: mov    $0x0,%eax

       0x00000000004009c7 <+25>: callq  0x43fc70 <syscall>

       ...

    End of assembler dump.

    (gdb) disass 0x43fc70

    Dump of assembler code for function syscall:

       0x000000000043fc70 <+0>:  mov    %rdi,%rax

       0x000000000043fc73 <+3>:  mov    %rsi,%rdi

       0x000000000043fc76 <+6>:  mov    %rdx,%rsi

       0x000000000043fc79 <+9>:  mov    %rcx,%rdx

       0x000000000043fc7c <+12>: mov    %r8,%r10

       0x000000000043fc7f <+15>: mov    %r9,%r8

       0x000000000043fc82 <+18>: mov    0x8(%rsp),%r9

       0x000000000043fc87 <+23>: syscall

       ...

    End of assembler dump.

    5 结论

    1. 系统调用指令:

    传统的32位系统调用int 0x80

    Intel的sysenter/sysexit

    AMD的syscall/sysret

     

    2. 传统Int 0x80系统调用

    系统调用号:EAX

    参数:EBX、ECX、EDX、ESI、EDI、EBP

    返回值:EAX

     

    3. 32位系统调用sysenter

    系统调用号:EAX

    参数:EBX、ECX、EDX、ESI、EDI、EBP

    返回值:EAX

     

    静态链接时,采用"call *_dl_sysinfo"指令;

    动态链接时,采用"call *%gs:0x10"指令;

    最终调用的是VDSO(linux-gate.so.1)中的__kernel_vsyscall函数;

    __kernel_vsyscall函数包含sysenter指令;

    syscall()函数也是类似的,根据静态/动态链接的不同分别采用的不同的指令,最终调用__kernel_vsyscall函数;

     

    4. 64位系统调用syscall

    系统调用号:RAX

    参数:RDI、RSI、RDX、R10、R8、R9

    返回值:RAX

     

    静态链接时,直接调用syscall指令;

    动态链接时,调用libc的系统调用代码,调用syscall指令;

    syscall()函数也是类似的,最终调用syscall指令;

    参考文章

    1. 64位Linux下的系统调用。http://www.lenky.info/archives/2013/02/2199。

    2. Linux 2.6 对新型 CPU 快速系统调用的支持。https://www.ibm.com/developerworks/cn/linux/kernel/l-k26ncpu/index.html。

     

     

    展开全文
  • 在计算机中,系统调用(英语:system call),又称为系统呼叫,指运行在使用者空间的程序向 操作系统内核请求需要更高权限运行的服务。系统调用提供了用户程序与操作系统之间的接口( 即系统调用是用户程序和内核...
  • 操作系统的系统调用

    千次阅读 2018-10-26 21:21:12
    系统调用:操作系统的接口是连接应用软件与操作系统的中间桥梁。接口在程序设计中表现的形式就是:函数。操作系统提供的函数就被称为系统调用(system call)。这里有个标准POSIX(Portable Operating System ...
  • Linux系统编程——Linux系统调用

    千次阅读 多人点赞 2015-04-17 20:40:33
    系统调用概述 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、...
  • 系统调用与库函数调用

    千次阅读 2017-01-17 21:15:43
    对上的话则暴露出来一些接口,供上层调用,这些接口就叫做系统调用。shell是包裹在linux内核外层的,一个可通过一系列的linux命令对操作系统发出相关指令的人机交互界面。库函数是在系统调用的基础上
  • 系统调用和函数调用

    千次阅读 2015-11-24 13:42:25
    系统调用和函数调用1. 系统调用a. 什么是系统调用系统调用,通俗的讲,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件...
  • 系统调用、函数调用

    千次阅读 2015-04-16 08:43:23
    1、系统调用 操作系统的主要功能是为管理硬件资源和为应用程序开发人员提供良好的环境来使应用程序具有更好的兼容性,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system ...
  • Linux系统调用和库函数调用

    千次阅读 2013-06-13 14:18:53
    Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions)。可以参考《Linux程序设计》(英文原版为《Beginning Linux Programming》,作者是Neil Matthew和Richard Stones)第三章:...
  • 系统调用和库函数调用的区别

    千次阅读 2018-09-04 16:19:24
    一:系统调用和库函数调用的区别: 1:系统调用是最底层的应用,是面向硬件的。而库函数的调用是面向开发的,相当于应用程序的API(即预先定义好的函数)接口; 2:各个操作系统的系统调用是不同的,因此系统调用...
  • 操作系统作业:给linux系统增加一个系统调用

    万次阅读 多人点赞 2018-06-01 00:43:37
    前不久开了一门《操作系统》,老师上课留下了一个作业——给Linux系统添加一个系统调用。刚开始只能用一脸懵逼来形容,只能硬着头皮做下去。由于刚的新电脑,所以就没敢装双系统。所以我选择了虚拟机,虚拟机刚开始...
  • TCP 系统调用

    千次阅读 2016-03-24 17:06:46
    典型的 TCP 客户机和服务器应用程序通过发布 TCP 系统调用序列来获取某些函数。这些系统调用包括socket ()、bind ()、listen ()、accept ()、send () 和 receive()。本文介绍在应用程序发布 TCP 系统...
  • 系统调用与普通过程调用的异同点

    千次阅读 2019-11-24 10:48:33
    系统调用与普通过程调用的异同点系统调用与普通过程调用的异同点 系统调用与普通过程调用的异同点 相同点: 改变指令流程 重复执行和公用 改变指令流程后需要返回原处 不同点: 系统调用是动态调用,而CALL调用方式...
  • 系统调用知识框架图2.系统调用和库函数的区别3.系统调用的执行过程 1.系统调用知识框架图 2.系统调用和库函数的区别 3.系统调用的执行过程 参考:《2021王道操作系统考研》 bilibili : ...
  • 系统调用接口

    千次阅读 2018-11-27 09:53:59
    1、系统调用 操作系统作为系统软件,它的任务是为用户的应用程序提供良好的运行环境。因此,由操作系统内核提供一系列内核函数,通过一组称为系统调用的接口提供给用户使用。系统调用的作用是把应用程序的请求传递...
  • 浅谈C语言函数调用与系统调用

    千次阅读 2019-11-12 09:55:50
    1. 函数调用和系统调用概述 1.1 定性的去区分函数调用和系统调用 很多初学C语言的同学,亦或者开发中很少接触系统底层的同学可能会认为函数调用以及系统调用是一回事。因为在应用程序,两者都被抽象成接口去给应用...
  • 系统调用和函数调用的区别

    万次阅读 2018-06-06 22:51:57
    系统调用 操作系统服务的编程接口 通常由高级语言编写(C或C++) 程序访问通常通过高层次 的API接口(C标准库的库函数)而不是直接进行系统调用 每个系统调用对应一个系统调用编号 系统调用与函数调用的区别 ...
  • 什么是系统调用? Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,...
  • 系统调用和函数调用区别

    千次阅读 2017-10-20 10:53:15
    系统调用和函数调用 1. 系统调用 a. 什么是系统调用 系统调用,通俗的讲,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以...
  • C++ 函数调用和系统调用的区别

    千次阅读 2018-02-06 10:59:27
     所谓系统调用就是用户在程序中调用操作系统所提供的一个子功能,也就是系统API,系统调用可以被看做特殊的公共子程序。系统中的各种共享资源都由操作系统统一掌管,因此在用户程序中,凡是与资源有关的操作(如...
  • 操作系统中系统调用的执行过程

    千次阅读 2019-02-21 12:56:59
    1、硬件接收到中断信号,立刻保存现场,并查找中断向量表,将CPU控制权转交给系统调用总入口程序。 2、对于系统调用总入口程序,也要先保存现场,将参数保存在内核的堆栈中。然后查找系统调用表,将CPU控制权转交给...
  • 操作系统实验之系统调用

    千次阅读 2016-09-07 21:54:24
    操作系统实验之系统调用
  • 系统调用和库函数的区别

    千次阅读 2018-05-27 22:15:57
    原文地址系统调用和库函数的区别 前言 从用户的角度来看,系统调用和库函数似乎没有什么区别,它们都是以C函数的形式出现,并且两者都为应用程序提供服务。但从实现者角度来看,它们之间是有根本的区别。那么,...
  • read 系统调用剖析

    千次阅读 2015-11-20 17:27:37
    Read 系统调用在用户空间中的处理过程 Linux 系统调用(SCI,system call interface)的实现机制实际上是一个多路汇聚以及分解的过程,该汇聚点就是 0x80 中断这个入口点(X86 系统结构)。也就是说,所有系统调用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,321,561
精华内容 1,328,624
关键字:

常见的系统调用