[笔记] Linux 系统调用

less than 1 minute read

《趣谈 Linux 操作系统》专栏第5讲笔记

Linux 系统调用

进程管理

创建进程的系统调用是 fork。创建新的进程是通过老的进程(父进程,Parent Process)调用 fork 来实现的。新的进程也叫做子进程(Child Process)

执行 fork 时,子进程将父进程的数据结构和程序代码都拷贝了一份。如何区分父子进程呢?通过 fork 调用的返回值来实现:如果当前进程是子进程,就返回 0;如果当前进程是父进程,就返回子进程的进程号

如果是父进程,还接着做原来应该做的事情;如果是子进程,需要请求另一个系统调用 execve 来执行另一个程序。

父进程通过系统调用 waitpid ,将子进程的进程号作为参数传给它,就能知道子进程是否运行完成和运行的结果。

内存管理

每个进程都有自己的内存,互不干扰,有独立的进程内存空间

进程的内存空间分为:

  1. 代码段(Code Segment):存放进程的程序代码。
  2. 数据段(Data Segment):存放进程运行过程中产生的数据。
    • 其中局部变量的部分,在当前函数执行的时候起作用,当进入另一个函数时,这个变量就释放了
    • 也有动态分配的,会较长时间保存,指明才销毁的,这部分称为堆(Heap)

进程的内存空间很大,对于 32 位操作系统是 4G,即2^32 Byte。

在堆里分配内存有两个常用的系统调用:

  • brk:分配的内存数量比较小,和原来的堆的数据连在一起
  • mmap:分配的内存数量比较大,会重新划分一块区域,不和之前的堆连在一起了

文件管理

文件操作中最重要的系统调用:

  • open:打开已有的文件
  • close:关闭文件
  • create:创建文件
  • lseek:打开文件后,使用 lseek 跳到文件的某个位置
  • read:读文件
  • write:写文件

简单理解 Linux 中一切皆文件的思想:

  • 运行的程序是二进制文件
  • 配置是文本文件
  • 执行命令时在 terminal 的输出是 stdout 文件
  • 管道也是文件
  • Socket 是文件
  • 设备是文件
  • 文件夹也是文件 :warning:
  • 查看进程运行情况时,可以看 /proc 目录下的进程号文件

每个文件都有一个文件描述符(File Descriptor,简称为 FD),是一个整数。

信号处理

每种信号都定义了默认动作,例如硬件故障,默认终止(SIGKILL)。

可以通过 sigaction 系统调用,注册一个信号处理函数。

进程间通信

  • 消息队列:适用于数据量小的情况。注意,这个消息队列不是那些个中间件,而是在内核中的。
    • 通过 msgget 创建新队列
    • 通过 msgsnd 将消息发送到队列中
    • 通过 msgrcv 从队列中取消息
  • 共享内存:适用于进程间需要交互的信息比较大的情况
    • 通过 shmget 创建共享内存块
    • 通过 shmat 将共享内存映射到进程的内存空间
    • 信号量 Semaphore 来解决多个进程间竞争共享内存中数据的问题

网络通信

  • 不同机器的网络通信遵循同一套网络协议,即 TCP/IP 协议栈。
  • 通过 Socket 提供网络服务
  • Socket 也是一个文件,也有其文件描述符。可以通过读写函数进行通信。
  • 通过 Socket 系统调用建立 Socket

Glibc

我们写程序时不会直接使用系统调用,而是通过一个 C 库 Glibc 来做到。

Glibc 对系统调用做了封装,为编写上层程序提供 API。

:construction: 问题

  • 有哪些信号呢?除了自己知道的 SIGKILL,SIGHUP 等。它们的含义和应用场景

Tags: ,

Categories:

Updated:

Comments