9.5 UNIX系统调用
UNIX系统是多任务、多用户的操作系统,其强大功能部分源于它提供的丰富的系统调用集。这些系统调用使得UNIX系统能够高效地管理进程、文件、通信等资源。随着UNIX系统的发展,系统调用的数量已从早期的56条增加到数百条,其中一些系统调用特别常用。本节将重点介绍UNIX系统中与进程控制相关的一些关键系统调用。
9.5.1 进程控制
进程控制是操作系统中最基本的功能之一,UNIX系统提供了一系列系统调用来管理进程的生命周期和行为。
进程的创建和终止
-
fork:
fork
系统调用允许一个进程创建一个新的进程。新创建的子进程是父进程的副本,继承了父进程的环境、文件描述符、当前工作目录等。fork
调用返回两次,一次在父进程中,返回子进程的PID;一次在子进程中,返回0。 -
exit:
exit
系统调用用于终止进程的执行。进程通过exit
调用正常退出时,可以返回一个状态码,表明进程的结束状态。该状态码可被父进程通过wait
系统调用获取。
改变进程映像和等待
-
exec:
exec
系列函数(如execl
、execv
等)用于在当前进程中加载并执行一个新程序。这意味着exec
调用会替换当前进程的代码和数据段,但进程ID等信息保持不变。 -
wait:
wait
系统调用使父进程暂停执行,直到一个子进程结束。它允许父进程获取子进程的终止状态。
其他进程调用
-
进程ID:UNIX系统提供了多个系统调用来获取进程的ID信息,如
getpid
用于获取当前进程的ID,getppid
获取父进程的ID,getpgrp
获取进程组ID等。 -
用户ID:类似地,UNIX系统也提供了系统调用来获取用户的ID信息,如
getuid
获取真实用户ID,geteuid
获取有效用户ID等。 -
pause:
pause
系统调用使进程挂起直到收到一个信号。这是进程等待外部事件的一种方式。
UNIX系统调用提供了操作系统的基本服务,允许用户程序以标准化的方式执行核心任务,如进程控制、文件操作和进程间通信等。这些调用是UNIX操作系统强大功能的基础,使得UNIX能够管理复杂的多任务和多用户环境。通过这些系统调用,UNIX系统为应用程序提供了高效、可靠的服务,支持了广泛的软件应用开发和系统管理工作。
9.5.2 文件操纵
文件操纵是UNIX系统提供的一类极为重要的系统调用,涉及到文件的创建、删除、打开、关闭、读取、写入等操作。这些系统调用构成了文件管理的基础,使得UNIX系统在文件操作方面表现出极高的灵活性和效率。以下是关于文件操作的一些核心系统调用的简要介绍。
文件的创建和删除
创建文件 (creat)
creat
系统调用用于创建一个新文件或重写一个已存在的文件。如果目标文件不存在,系统将根据指定的文件名和许可权限创建新文件;如果文件已存在,则先释放原文件的数据块。- 创建成功后,文件会被自动打开,并返回一个文件描述符(
fd
),供后续操作使用。若创建失败,返回“-1”。
删除文件
- UNIX系统中没有专门用于删除文件的系统调用。文件的删除是通过
unlink
系统调用间接完成的,它减少文件的链接计数,当计数降至0时,文件被删除。
文件的打开和关闭
打开文件 (open)
open
系统调用用于打开一个已存在的文件。它将文件的属性从磁盘读入内存,并在用户程序和指定文件之间建立一个快捷通道,返回一个文件描述符(fd
)。- 通过文件描述符,用户可以执行后续的文件操作,而无需再次指定文件路径。
关闭文件 (close)
close
系统调用用于关闭已打开的文件,断开用户程序与该文件的连接。如果文件被多个进程共享,只有当所有引用计数减至0时,文件才真正关闭。
文件的读和写
读文件 (read)
read
系统调用从一个已打开的文件中读取数据。用户需提供文件描述符、目标缓冲区地址和要读取的字节数。成功读取后,数据被存储在指定的缓冲区中。
写文件 (write)
write
系统调用将数据写入一个已打开的文件。用户需指定文件描述符、数据源的缓冲区地址和要写入的字节数。
建立与文件的连接和去连接
连接 (link)
link
系统调用增加了文件的链接计数,以实现文件共享。每当一个新的用户或进程需要共享该文件时,链接计数增加。
去连接 (unlink)
unlink
系统调用用于断开与文件的链接。它减少文件的链接计数,当计数降至0时,文件即可从文件系统中删除。
通过这些系统调用,UNIX系统为用户和程序员提供了强大而灵活的文件操作能力。它们不仅支持基本的文件操作,还允许复杂的文件共享和访问控制,是UNIX系统强大功能的体现之一。
9.5.3 进程通信和信息保护
UNIX系统为了支持进程间的通信和同步,提供了一套丰富的进程通信(IPC)机制。这些机制包括消息队列、共享内存和信号量,它们通过系统调用的形式提供给用户程序使用。此外,UNIX系统还提供了多种用于信息维护的系统调用,使得用户和超级用户能够获取和设置系统信息,如时间、系统名称等。
1. 进程通信
消息机制
- 消息队列:通过
msgget
系统调用创建消息队列。一旦创建成功,返回一个消息队列标识符(msgid
),之后可使用此标识符进行消息的发送(msgsend
)和接收(msgrcv
)。这种机制支持不同进程间的异步通信。
共享存储器机制
- 共享内存:通过
shmget
系统调用创建共享内存区,成功时返回一个共享内存标识符(shmid
)。进程需要通过shmat
(attach)将共享内存连接到自己的地址空间,之后就可以直接访问这段内存以实现进程间通信。共享内存是最快的IPC机制,因为它避免了数据的复制。
信号量机制
- 信号量:UNIX提供了一套信号量操作,类似于传统的信号量概念,支持进程间的同步操作。信号量可以是单个信号量或信号量集,通过原子操作实现进程间的互斥和条件同步。
2. 信息维护
设置和获取时间
- 时间设置与获取:超级用户可以使用
stime
系统调用设置系统时间和日期,而所有用户都可以使用time
系统调用获取当前的系统时间。
获取进程和子进程时间
- 进程时间:
times
系统调用允许进程获取自己以及其子进程消耗的CPU时间,包括用户空间和内核空间的时间。
设置文件访问和修改时间
- 文件时间:
utime
系统调用用于设置文件的最后访问时间和最后修改时间,这对于保持文件状态的跟踪非常有用。
获取系统名称
- 系统名称:
uname
系统调用提供了一种获取当前运行的UNIX系统信息的方式,包括系统名称、网络名称和硬件类型等。
这些进程通信机制和信息维护功能的提供,是UNIX系统支持复杂多用户环境和高效进程管理的关键。它们为开发者提供了强大的工具集,以实现高效、安全的进程间通信和系统管理操作。