APUE学习笔记之UNIX基础知识

所有操作系统都为它们所运行的程序提供服务。典型的服务包括:执行新程序、打开文件、读文件、分配存储区以及获得当前时间等。

  1. UNIX体系结构
    (1)从严格意义上说,可将操作系统定义为一种软件它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kernel),因为它相对较小,而且位于环境的核心。
    (2)内核的接口被称为系统调用(system call)。
    (3)shell是一个特殊的应用程序,为运行其他应用程序提供了一个接口:
    1)shell是一个命令解释器,它读取用户输入,然后执行。
    2)shell的用户输入通常来自于终端(交互式shell),有时来自于文件(称为shell脚本)。
  2. 文件和目录
    (1)文件系统
    UNIX文件系统是目录和文件的一种层次结构,所有东西的起点是称为根(root)的目录,这个目录的名称是一个字符“/”。
    (2)文件名
    1)目录终端各个名字称为文件名。只有斜线(/)和空字符这两个字符不能出现在文件名中。
    2)创建新目录时会自动创建两个文件名:.(点)和..(点点)。分别指向当前目录和父目录。
    (3)路径名
    由斜线分隔的一个或多个文件名组成的序列(也可以斜线开头)构成路径名(pathname)。
    (4)实例
  3. 输入和输出
    (1)文件描述符
    文件描述符(file description)通常是一个小的非负整数,内核用以标识一个特定进行正在访问的文件。当内核打开一个现有文件或创建一个新文件时,它都返回一个文件描述符。在读、写文件时,可以使用这个文件描述符。(2)标准输入、标准输出和标准错误
    1)按惯例,每当运行一个新程序时,所有的shell都为其打开3个文件描述符:标准输入、标准输出、标准错误。
    2)大多数shell都提供一种方法,使其中任何一个或所有这三个描述符都能重新定向到某个文件,例如:
    ls > file.list    #执行ls,其标准输出重新定向到名为file.list的文件。(3)不带缓冲的I/O
    函数open, read, write, lseek以及close提供了不带缓冲的I/O。这些函数都使用文件描述符。
    (4)标准I/O
    1)标准I/O函数为那些不带缓冲的I/O函数提供了一个带缓冲的接口。使用标准I/O函数无需担心如何选取最佳的缓冲区大小。
    2)标准I/O函数还简化了对输入行的处理。例如,fgets函数读取一个完整的行,而read函数读取指定字节数。
    实例:用标准I/O将标准输入复制到标准输出

    其中,getc函数一次读取一个字符,然后函数putc将此字符写到标准输出。
  4. 程序和进程
    (1)程序
    程序(program)是一个存储在磁盘上某个目录中的可执行文件。内核使用exec函数(7个exec函数之一),将程序读入内存,并执行程序。
    (2)进程和进程ID
    程序的执行实例被称为进程(process)。UNIX系统确保每个进程都有一个唯一的数字标识符,称为进程ID(process ID),进程ID总是一个非负整数。
    实例:打印进程ID

    其中,getpid函数得到进程ID,返回一个pid_t数据类型。

    (3)进程控制
    有3个用于进程控制的主要函数:fork, exec, waitpid。(exec函数有7种变体,但经常把它们统称为exec函数)

    (4)线程和线程ID
    1)通常,一个进程只有一个控制线程(thread)——某一时刻执行的一组机器指令。对于某些问题,如果有多个控制线程分别作用于它的不同部分,那么解决起来就容易的多。另外,多个控制线程也可以充分利用多处理器系统的并行能力。
    2)一个进程内的所有线程共享同一地址空间、文件描述符、栈以及与进程相关的属性。
    3)与进程相同,线程也用ID标识。但是,线程ID只在它所属的进程内起作用。
    4)控制线程的函数与控制进程的函数类似,但另有一套。

  5. 出错处理
    (1)当UNIX系统函数出错时,通常会返回一个负值,而且整型变量errno通常被设置为具有特定信息的值。
    (2)文件<errno.h>中定义了errno以及可以赋予它的各种常量,这些常量都以字符E开头。
  6. 信号
    信号(signal)用于通知进程发生了某种情况。例如,当某一进程执行除法操作,其除数为0,则将名为SIGFPR(浮点异常)的信号发送给该进程。进程有以下3种处理信号的方式:
    (1)忽略信号
    (2)按系统默认方式处理。对于除数为0,系统默认方式是终止该进程。
    (3)提供一个函数,信号发生时调用该函数,这种称为捕捉该信号。通过提供自编的函数,我们就能知道什么时候产生了信号,并按期望的方式处理它。很多情况下都会产生信号,终端键盘上有两种产生信号的方法,分别称为中断键(interrupt key,通常是Delete键或Ctrl+C)和退出键(quit key, 通常是Ctrl+\)。
    另一种产生信号的方法是调用kill函数。在一个进程中调用此函数就可向另一个进程发送一个信号。当然这样做也有些限制:当向一个进程发送信号时,我们必须是那个进程的所有者或者是超级用户

发表评论

电子邮件地址不会被公开。 必填项已用*标注