一、进程间通讯方式
在 Linux 系统中,进程间通讯(IPC)是实现不同进程之间数据交互和协同工作的重要机制,常见的通讯方式有以下几种:
管道(Pipe)及有名管道(named pipe):
管道:是一种半双工的通信方式,数据只能单向流动,且只能在具有亲缘关系(如父子进程)的进程间使用。它在创建时会在内核中开辟一块缓冲区,用于数据的传输。
有名管道:克服了管道只能在亲缘关系进程间通信的限制,它以文件的形式存在于文件系统中,通过文件名来访问。不同进程只要拥有对该文件的访问权限,就可以进行通信。
信号(Signal):是一种异步通信机制,用于通知进程发生了某种事件。信号可以由系统内核、其他进程或用户手动发送,进程接收到信号后会根据预先设置的信号处理函数来做出相应的响应,如终止进程、暂停进程等。
报文(Message)队列(消息队列):消息队列是一个消息的链表,存放在内核中。进程可以向消息队列中发送消息,也可以从消息队列中读取消息。消息队列可以实现不同进程间的消息传递,并且可以根据消息的类型进行分类处理。
共享内存:是一种高效的进程间通信方式,它允许不同进程访问同一块内存区域。进程可以直接对共享内存进行读写操作,从而实现数据的共享。为了保证数据的一致性和正确性,使用共享内存时需要配合信号量等同步机制来避免数据冲突。
信号量(semaphore):本质上是一个计数器,用于控制对共享资源的访问。它可以实现进程间的同步和互斥,确保在同一时刻只有一个或多个进程可以访问共享资源,防止数据竞争和不一致的问题。
套接口(Socket):是一种通用的进程间通信机制,不仅可以用于同一台主机上的进程间通信,还可以用于不同主机之间的网络通信。Socket 支持多种通信协议,如 TCP、UDP 等,根据不同的需求可以选择合适的协议进行通信。
二、内存管理相关
(一)内存申请函数
在 C 语言中,常用的内存申请函数有以下几个,它们在动态内存分配中起着关键作用:
calloc:函数会在内存中分配一块指定大小的内存空间,并将该空间的所有字节初始化为 0。它接受两个参数,分别是元素个数和每个元素的大小,返回指向分配内存的指针。例如,calloc(10, sizeof(int)) 会分配 10 个 int 类型大小的内存空间,并初始化为 0。
malloc:用于分配指定字节数的内存空间。它只有一个参数,即要分配的字节数,返回指向分配内存的指针。如果分配失败,返回 NULL。例如,int *ptr = malloc(10 * sizeof(int)) 分配了 10 个 int 类型大小的内存空间。
realloc:可以重新调整已分配内存的大小。它接受两个参数,第一个是指向已分配内存的指针,第二个是新的内存大小。如果重新分配成功,返回指向新内存的指针;如果失败,返回 NULL。例如,ptr = realloc(ptr, 20 * sizeof(int)) 可以将原来分配的内存空间大小调整为 20 个 int 类型大小。
(二)Linux 内存分配说明
在 Linux 系统中,内存被划分为多个区域,每个区域有其特定的用途和特点,存放不同类型的数据:
内存区域 存放数据 说明
| 静态存储区 | 静态数据、全局数据、常量 | 在程序编译的时候就已经分配好,其生命周期与程序的运行周期相同,在程序结束时才会被释放。 |
| 栈区 | 局部变量、函数参数 | 栈内存分配运算内置于处理器的指令集中,因此效率很高,但栈的大小有限,分配的内存容量相对较小。当函数调用时,局部变量和函数参数会被压入栈中;函数返回时,这些数据会被弹出栈。 |
| 堆区 | malloc 申请的内存 |
用于动态内存分配,需要程序员手动使用 free 函数来释放内存,否则可能会导致内存泄漏。堆内存的分配比较灵活,可以根据程序的需求动态调整大小。 |
| 代码区 | 代码 | 存放函数体的二进制代码,是程序执行的指令集合。代码区是只读的,防止程序意外修改自身的指令。 |
| 文字常量区 | 常量字符串 | 程序结束后由系统释放,存放程序中定义的常量字符串,这些字符串在程序运行过程中不会被修改。 |
三、GCC 编译过程
GCC(GNU Compiler Collection)是 Linux 系统中常用的编译器,它将 C/C++ 等源程序编译成可执行文件需要经过多个步骤,每个步骤都有其特定的作用和生成的文件:
过程 生成文件 说明
| 预编译 | *.i |
预处理器首先处理源文件中的预处理指令,如 #include(包含头文件)、#define(宏定义)等,将头文件的内容插入到源文件中,并展开宏定义。经过预编译后,生成一个 .i 文件,该文件包含了展开后的源代码。 |
| 编译 | *.s |
编译器将预编译后的 .i 文件进行语法分析、语义分析和优化等操作,生成汇编代码,保存在 .s 文件中。 |
| 汇编 | *.o |
汇编器将汇编代码转换为机器可执行的目标代码,生成 .o 文件。每个 .c 文件经过编译和汇编后都会生成一个对应的 .o 文件。 |
| 链接 | 可执行文件 | 链接器将多个 .o 文件以及所需的库文件进行链接,解析符号引用,将各个目标文件和库文件中的代码和数据组合成一个完整的可执行文件。 |
四、文件系统
文件系统是 Linux 系统中用于组织和存储文件的重要机制,常见的文件系统有以下几种,它们在不同的场景中有着各自的优势和应用:
文件系统 说明
fat |
早期广泛使用的文件系统,兼容性好,支持多种操作系统,但安全性和性能相对较低,不支持大文件和长文件名。 |
fat32 |
是 fat 文件系统的扩展,支持更大的分区和文件,提高了对大文件的支持能力,但仍然存在一些局限性,如单个文件大小不能超过 4GB。 |
ntfs |
是 Windows 系统常用的文件系统,具有较高的安全性和性能,支持文件压缩、加密、权限管理等功能,但在 Linux 系统中对 ntfs 的支持相对有限。 |
ext2 |
是 Linux 系统早期的文件系统,具有较好的性能和稳定性,但不支持日志功能,在系统崩溃时可能会导致数据丢失。 |
ext3 |
在 ext2 的基础上增加了日志功能,提高了文件系统的可靠性和数据安全性,当系统崩溃时可以通过日志恢复文件系统的一致性。 |
ext4 |
是 ext3 的升级版本,进一步提高了性能、支持更大的文件和分区,并且增加了一些新的特性,如延迟分配、多块分配等,是目前 Linux 系统中常用的文件系统之一。 |
nfs |
网络文件系统,允许不同的计算机通过网络共享文件和目录,使得用户可以像访问本地文件系统一样访问远程的文件资源,常用于分布式系统和网络存储环境中。 |
五、硬链接和软连接
在 Linux 系统中,链接是一种特殊的文件,用于指向其他文件或目录,分为硬链接和软链接(符号链接),它们在实现方式和特点上有所不同:
(一)硬链接
硬链接直接指向文件的 i 节点(索引节点),它和原文件具有相同的 i 节点,共享相同的数据和属性。因此,硬链接文件显示的大小和原文件是一样的,并且对原文件的修改也会反映在硬链接文件中。需要注意的是,硬链接不能链接目录文件,因为这可能会导致目录结构的混乱。例如:
ln file2 /home/xiaxiaowen/file2hard
上述命令创建了一个名为 file2hard 的硬链接,指向 file2 文件。
(二)软链接(符号链接)
软链接则是建立了一个新的文件,这个文件包含了指向目标文件的路径信息。软链接文件和原文件的 i 节点不一样,它类似于一个快捷方式。软链接可以链接目录,并且当原文件被删除或移动时,软链接会变成无效链接。例如:
ln -s file2 /home/xiaxiaowen/file2soft
上述命令创建了一个名为 file2soft 的软链接,指向 file2 文件。
六、Linux 内核子系统
Linux 内核是操作系统的核心部分,由多个子系统组成,这些子系统协同工作,提供了系统的基本功能和服务:
进程管理:负责进程的创建、调度、终止等操作,管理进程的生命周期。它包括进程的状态转换(如运行态、就绪态、阻塞态之间的转换)、进程间的通信和同步等功能,确保系统中多个进程能够高效、有序地运行。
内存管理:对系统的内存资源进行分配、回收和管理,包括物理内存和虚拟内存的管理。内存管理子系统负责将内存分配给进程使用,并通过虚拟内存技术使得进程能够使用比实际物理内存更大的地址空间,同时还需要处理内存的换入换出等操作,以提高内存的利用率。
I/O 管理:管理系统的输入输出设备,包括磁盘、网卡、串口等设备。它负责设备的驱动程序管理、数据的读写操作以及设备的中断处理等,为用户和应用程序提供了统一的 I/O 接口,使得应用程序可以方便地访问各种设备。
文件系统管理:负责管理文件系统的创建、挂载、卸载以及文件的读写、目录的操作等。文件系统管理子系统提供了对文件和目录的组织和存储功能,使得用户可以方便地存储和访问数据。
七、进程状态
在 Linux 系统中,进程有多种状态,这些状态反映了进程在不同时刻的运行情况:
运行态:进程正在处理器上执行,占用 CPU 资源。在单处理器系统中,同一时刻只有一个进程处于运行态;在多处理器系统中,可能有多个进程同时处于运行态。
就绪态:进程已经准备好执行,但由于 CPU 资源有限,暂时没有被调度到处理器上运行。就绪态的进程在就绪队列中等待调度,一旦获得 CPU 资源,就可以立即进入运行态。
阻塞态:进程因为等待某个事件的发生(如 I/O 操作完成、等待信号等)而暂时无法继续执行,此时进程会进入阻塞态。在阻塞态下,进程不会占用 CPU 资源,直到所等待的事件发生,进程才会从阻塞态转换为就绪态。
八、文件系统组成
Linux 文件系统由多个部分组成,每个部分都有其特定的功能和作用,共同构成了文件系统的完整结构:
超级块:存放文件系统本身的信息,比如文件系统的类型、每个区域的大小、未被使用的磁盘块的信息等。不同版本的文件系统,超级块的具体内容可能会稍有差别。超级块是文件系统的关键部分,它描述了文件系统的整体布局和属性。
i-节点表:每个文件都有其属性,如文件的大小、所有者、最近修改时间等,这些属性被存储在 ino_t 的结构体中,称为 i 节点。所有的 i 节点都有相同的大小,i 节点表就是这样一些节点的列表。表中的每个 i 节点都通过位置来标识,例如标识为 2 的 i 节点位于文件系统 i 节点表中的第 3 个位置(因为索引通常从 0 开始计数)。i 节点是文件系统中用于管理文件属性和数据存储位置的重要数据结构。
数据块:用于存放文件的内容。由于数据块的大小是固定的,所以有时一个文件会分布在多个数据块上,甚至可能分布在多个磁盘上。数据块是文件数据的实际存储单元,文件系统通过 i 节点来记录文件数据在数据块中的存储位置。
九、i 节点
i 节点是一个 64 字节长的表,表中包含了文件的相关信息,是文件系统中非常重要的数据结构。其中包含了文件的大小、文件所有者、文件的存取许可方式以及文件的类型等重要信息。通过 i 节点,文件系统可以快速地定位和管理文件的属性和数据存储位置。每个文件都有一个唯一的 i 节点,文件系统通过 i 节点来区分不同的文件。
十、Linux 文件类型
在 Linux 系统中,文件可以分为多种类型,不同类型的文件具有不同的特点和用途,通过文件的属性可以进行区分:
文件类型 属性 说明
| 普通文件 | - |
包含数据、程序代码等内容的文件,如文本文件、可执行文件等。 |
| 目录 | d |
用于组织和管理文件和目录的特殊文件,类似于 Windows 系统中的文件夹。目录中包含了文件和子目录的信息。 |
| 字符设备文件 | c |
用于表示字符设备,如串口、终端等,这些设备以字符流的方式进行数据传输。 |
| 块设备文件 | b |
用于表示块设备,如硬盘、磁盘分区等,这些设备以块为单位进行数据存储和传输。 |
| 符号链接文件 | l |
也称为软链接,是一种特殊的文件,它指向另一个文件或目录,类似于快捷方式。 |
| 套接字文件 | s |
用于实现进程间的网络通信,是网络编程中常用的文件类型。 |
| 管道文件 | p |
用于实现进程间的通信,分为匿名管道和有名管道,是一种半双工的通信方式。 |
十一、Linux 常用系统调用函数
Linux 系统提供了丰富的系统调用函数,用于实现各种系统功能,这些函数是用户空间程序与内核进行交互的接口。根据功能的不同,可以将系统调用函数分为以下几类:
(一)进程控制函数
进程控制函数用于管理进程的生命周期,包括进程的创建、运行、终止等操作:
函数 功能
fork |
创建一个新进程,新进程是原进程的副本,父子进程共享部分资源,如代码段等。 |
clone |
按指定条件创建子进程,可以更灵活地控制子进程的资源共享和行为。 |
execve |
运行可执行文件,用新的程序替换当前进程的内存空间,实现程序的执行。 |
exit |
中止进程,在终止进程前会进行一些清理工作,如关闭文件描述符、释放资源等。 |
_exit |
立即中止当前进程,不会进行过多的清理工作,直接结束进程的运行。 |
getdtablesize |
获取进程所能打开的最大文件数,用于限制进程对文件的访问数量。 |
getpgid |
获取指定进程组标识号,用于管理进程组的相关操作。 |
setpgid |
设置指定进程组标志号,用于改变进程所属的进程组。 |
getpgrp |
获取当前进程组标识号,返回当前进程所属的进程组 ID。 |
setpgrp |
设置当前进程组标志号,将当前进程设置为新的进程组组长。 |
getpid |
获取进程标识号,返回当前进程的唯一 ID。 |
getppid |
获取父进程标识号,返回当前进程的父进程的 ID。 |
getpriority |
获取调度优先级,用于了解进程在系统中的调度优先级。 |
setpriority |
设置调度优先级,调整进程在系统中的调度优先级,影响进程获取 CPU 资源的机会。 |
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 |
设置会话标识号 |
以下是对上一部分内容的继续完善,涵盖了剩余的系统调用函数分类以及其他重要的 Linux 软件开发知识点:
(二)文件操作函数
文件操作函数用于对文件进行各种操作,包括打开、关闭、读写、定位等:
函数 功能
fcntl |
文件控制,可用于设置文件的各种属性,如文件描述符标志、文件状态标志等。 |
open |
打开文件,返回一个文件描述符,用于后续对文件的操作。可以指定打开文件的模式(如只读、读写等)和权限。 |
creat |
创建新文件,如果文件已存在则截断其内容。可以指定文件的权限。 |
close |
关闭文件描述字,释放与文件相关的资源,如文件句柄等。 |
read |
从文件中读取数据,将数据读取到指定的缓冲区中。返回实际读取的字节数。 |
write |
向文件中写入数据,将缓冲区中的数据写入到文件中。返回实际写入的字节数。 |
readv |
从文件读入数据到缓冲数组中,适用于从文件中读取多个不连续的数据块。 |
writev |
将缓冲数组里的数据写入文件,适用于向文件中写入多个不连续的数据块。 |
pread |
对文件进行随机读,在不改变文件当前偏移量的情况下,从指定位置读取数据。 |
pwrite |
对文件进行随机写,在不改变文件当前偏移量的情况下,向指定位置写入数据。 |
lseek |
移动文件指针,调整文件的当前偏移量,用于随机访问文件中的数据。 |
_llseek |
在 64 位地址空间里移动文件指针,用于处理大文件的偏移量操作。 |
dup |
复制已打开的文件描述字,返回一个新的文件描述符,指向同一个文件。 |
dup2 |
按指定条件复制文件描述字,可以将一个文件描述符复制到另一个指定的文件描述符上。 |
flock |
文件加/解锁,用于实现对文件的独占或共享访问控制,避免多个进程同时修改文件导致数据不一致。 |
poll |
I/O 多路转换,用于监视多个文件描述符的状态,当其中一个或多个文件描述符准备好进行 I/O 操作时,函数返回。 |
truncate |
截断文件,将文件的长度缩短到指定的长度。如果文件长度大于指定长度,则截断超出部分;如果文件长度小于指定长度,则文件大小不变。 |
ftruncate |
与 truncate 类似,只不过操作的是已打开的文件。 |
umask |
设置文件权限掩码,用于控制新创建文件的默认权限。 |
fsync |
把文件在内存中的部分写回磁盘,确保文件的数据已实际写入磁盘,而不是仅仅存在于内存缓冲区中。 |
(三)文件系统操作函数
文件系统操作函数用于对文件系统进行管理,包括目录操作、文件权限设置、文件系统信息获取等:
函数 功能
access |
确定文件的可存取性,检查当前进程是否具有对指定文件的读、写或执行权限。 |
chdir |
改变当前工作目录,将当前进程的工作目录切换到指定的目录。 |
fchdir |
与 chdir 类似,只不过操作的是通过文件描述符指定的目录。 |
chmod |
改变文件方式,设置文件的访问权限,如读、写、执行权限等。 |
fchmod |
与 chmod 类似,只不过操作的是已打开的文件。 |
chown |
改变文件的属主或用户组,将文件的所有权或所属用户组更改为指定的用户或用户组。 |
fchown |
与 chown 类似,只不过操作的是已打开的文件。 |
lchown |
与 chown 类似,但是在处理符号链接时,操作的是符号链接本身,而不是其指向的文件。 |
chroot |
改变根目录,将当前进程的根目录更改为指定的目录,常用于创建一个隔离的文件系统环境。 |
stat |
取文件状态信息,获取文件的详细属性,如文件大小、修改时间、权限等。 |
lstat |
与 stat 类似,但是在处理符号链接时,返回的是符号链接本身的属性,而不是其指向的文件的属性。 |
fstat |
与 stat 类似,只不过操作的是已打开的文件。 |
statfs |
取文件系统信息,获取文件系统的相关信息,如总容量、可用空间等。 |
fstatfs |
与 statfs 类似,只不过操作的是已打开的文件所在的文件系统。 |
readdir |
读取目录项,用于读取目录中的文件和子目录信息。 |
getdents |
也是用于读取目录项,与 readdir 功能类似。 |
mkdir |
创建目录,在文件系统中创建一个新的目录。 |
mknod |
创建索引节点,用于创建特殊文件,如设备文件等。 |
rmdir |
删除目录,删除一个空目录。如果目录不为空,则无法删除。 |
rename |
文件改名,将文件或目录重命名为指定的名称。 |
link |
创建链接,创建一个硬链接,指向指定的文件。 |
symlink |
创建符号链接,创建一个软链接,指向指定的文件或目录。 |
unlink |
删除链接,删除指定的硬链接或文件。如果是符号链接,则删除符号链接本身。 |
readlink |
读符号链接的值,获取符号链接指向的目标文件或目录的路径。 |
mount |
安装文件系统,将文件系统挂载到指定的挂载点,使得文件系统可以被访问。 |
umount |
卸下文件系统,卸载已挂载的文件系统,使其不再可访问。 |
ustat |
取文件系统信息,获取文件系统的状态信息,如磁盘使用情况等。 |
utime |
改变文件的访问修改时间,设置文件的最后访问时间和最后修改时间。 |
utimes |
与 utime 类似,用于设置文件的时间戳。 |
quotactl |
控制磁盘配额,用于管理用户或用户组在文件系统上的磁盘使用限制。 |
(四)系统控制函数
系统控制函数用于对系统进行各种控制操作,如设置系统参数、获取系统信息、控制设备等:
函数 功能
ioctl |
I/O 总控制函数,用于对设备进行各种控制操作,如设置设备参数、获取设备状态等。 |
_sysctl |
读/写系统参数,用于读取和修改系统的内核参数,如网络参数、内存参数等。 |
acct |
启用或禁止进程记账,用于记录进程的资源使用情况,如 CPU 时间、内存使用等。 |
getrlimit |
获取系统资源上限,获取进程对某种系统资源(如文件描述符数量、内存大小等)的限制。 |
setrlimit |
设置系统资源上限,设置进程对某种系统资源的限制。 |
getrusage |
获取系统资源使用情况,获取进程或系统的资源使用统计信息,如 CPU 时间、内存使用等。 |
uselib |
选择要使用的二进制函数库,用于指定进程使用特定的函数库。 |
ioperm |
设置端口 I/O 权限,设置进程对特定端口的 I/O 访问权限。 |
iopl |
改变进程 I/O 权限级别,提升或降低进程的 I/O 权限级别,使其能够访问特定的 I/O 端口。 |
outb |
低级端口操作,用于对端口进行低级的读写操作。 |
reboot |
重新启动,用于重新启动系统。 |
swapon |
打开交换文件和设备,启用交换空间,将内存中的数据交换到磁盘上,以释放内存空间。 |
swapoff |
关闭交换文件和设备,禁用交换空间,将磁盘上的交换数据换回内存。 |
bdflush |
控制 bdflush 守护进程,用于管理磁盘缓冲区的刷新操作,确保数据及时写入磁盘。 |
sysfs |
取核心支持的文件系统类型,获取内核支持的文件系统类型列表。 |
sysinfo |
取得系统信息,获取系统的基本信息,如内存大小、CPU 数量等。 |
adjtimex |
调整系统时钟,用于调整系统的时间和时间间隔。 |
alarm |
设置进程的闹钟,设置一个定时器,在指定的时间后向进程发送 SIGALRM 信号。 |
getitimer |
获取计时器值,获取进程中指定类型的计时器的值。 |
setitimer |
设置计时器值,设置进程中指定类型的计时器的值和选项。 |
gettimeofday |
取时间和时区,获取当前的时间和时区信息。 |
settimeofday |
设置时间和时区,设置系统的时间和时区。 |
stime |
设置系统日期和时间,设置系统的日期和时间。 |
time |
取得系统时间,返回当前的系统时间,以秒为单位。 |
times |
取进程运行时间,获取进程的用户时间、系统时间和总运行时间。 |
uname |
获取当前 UNIX 系统的名称、版本和主机等信息,返回系统的标识信息。 |
vhangup |
挂起当前终端,挂起当前的终端会话。 |
nfsservctl |
对 NFS 守护进程进行控制,用于管理 NFS 服务器的守护进程,如启动、停止、重新加载等操作。 |
vm86 |
进入模拟 8086 模式,使进程进入模拟 8086 处理器的模式,用于兼容一些旧的软件。 |
create_module |
创建可装载的模块项,用于创建一个可装载的内核模块。 |
delete_module |
删除可装载的模块项,删除已装载的内核模块。 |
init_module |
初始化模块,初始化一个已装载的内核模块。 |
query_module |
查询模块信息,获取已装载内核模块的相关信息,如模块名称、版本、依赖关系等。 |
*get_kernel_syms |
取得核心符号,已被 query_module 代替,用于获取内核符号表中的符号信息。 |
(五)内存管理函数
内存管理函数用于对内存进行分配、释放、映射等操作,以满足程序对内存的需求:
函数 功能
brk |
改变数据段空间的分配,通过改变数据段的结束地址来调整数据段的大小。 |
sbrk |
与 brk 类似,用于调整数据段的大小,返回调整前数据段的结束地址。 |
mlock |
内存页面加锁,将指定的内存页面锁定在物理内存中,防止其被交换到磁盘上。 |
munlock |
内存页面解锁,解锁之前被锁定的内存页面,使其可以被交换到磁盘上。 |
mlockall |
调用进程所有内存页面加锁,将调用进程的所有内存页面锁定在物理内存中。 |
munlockall |
调用进程所有内存页面解锁,解锁调用进程的所有已锁定的内存页面。 |
mmap |
映射虚拟内存页,将文件或设备的一部分映射到进程的虚拟地址空间中,实现对文件或设备的内存映射访问。 |
munmap |
去除内存页映射,解除之前通过 mmap 建立的内存映射关系。 |
mremap |
重新映射虚拟内存地址,重新调整已映射内存的大小和位置。 |
msync |
将映射内存中的数据写回磁盘,确保映射内存中的数据与磁盘上的数据一致。 |
mprotect |
设置内存映像保护,设置内存区域的访问权限,如读、写、执行权限等。 |
getpagesize |
获取页面大小,返回系统中内存页面的大小。 |
sync |
将内存缓冲区数据写回硬盘,将所有已修改的文件系统缓冲区数据写回磁盘,确保数据的持久性。 |
cacheflush |
将指定缓冲区中的内容写回磁盘,用于刷新缓存,确保缓存中的数据与磁盘上的数据一致。 |
(六)网络管理函数
网络管理函数用于对网络进行配置和管理,包括设置主机名、域名、网络接口等:
函数 功能
getdomainname |
取域名,获取当前系统的域名。 |
setdomainname |
设置域名,设置当前系统的域名。 |
gethostid |
获取主机标识号,获取当前主机的唯一标识号。 |
sethostid |
设置主机标识号,设置当前主机的标识号。 |
gethostname |
获取本主机名称,获取当前主机的名称。 |
sethostname |
设置主机名称,设置当前主机的名称。 |
(七)socket 函数
socket 函数用于实现网络编程中的 socket 通信,包括创建 socket、绑定地址、连接服务器等操作:
函数 功能
socketcall |
socket 系统调用,用于进行 socket 相关的系统调用,是一个通用的 socket 操作接口。 |
socket |
建立 socket,创建一个 socket 描述符,指定 socket 的类型(如 TCP、UDP 等)和协议。 |
bind |
绑定 socket 到端口,将 socket 绑定到指定的 IP 地址和端口号,以便接收来自网络的连接请求。 |
connect |
连接远程主机,建立与远程主机的 socket 连接。 |
accept |
响应 socket 连接请求,接受来自客户端的 socket 连接请求,返回一个新的 socket 描述符用于与客户端进行通信。 |
send |
通过 socket 发送信息,向已连接的 socket 发送数据。 |
sendto |
发送 UDP 信息,向指定的 IP 地址和端口发送 UDP 数据报。 |
sendmsg |
与 send 类似,用于发送消息,支持更复杂的消息结构。 |
recv |
通过 socket 接收信息,从已连接的 socket 接收数据。 |
recvfrom |
接收 UDP 信息,从指定的 IP 地址和端口接收 UDP 数据报。 |
recvmsg |
与 recv 类似,用于接收消息,支持更复杂的消息结构。 |
listen |
监听 socket 端口,将 socket 设置为监听状态,等待客户端的连接请求。 |
select |
对多路同步 I/O 进行轮询,监视多个 socket 的状态,当其中一个或多个 socket 准备好进行 I/O 操作时,函数返回。 |
close |
关闭 socket 上的连接,关闭 socket 描述符,释放与 socket 相关的资源。 |
getsockname |
取得本地 socket 名字,获取 socket 绑定的本地 IP 地址和端口号。 |
getpeername |
获取通信对方的 socket 名字,获取与当前 socket 通信的对方的 IP 地址和端口号。 |
getsockopt |
取端口设置,获取 socket 的选项设置,如超时时间、缓冲区大小等。 |
setsockopt |
设置端口参数,设置 socket 的选项参数,如超时时间、缓冲区大小等。 |
sendfile |
在文件或端口间传输数据,将文件的内容直接发送到 socket 中,提高数据传输的效率。 |
socketpair |
创建一对已联接的无名 socket,创建一对相互连接的 socket,可用于进程间的通信。 |
(八)用户管理函数
用户管理函数用于对用户和用户组进行管理,包括获取用户和组的信息、设置用户和组的标识等:
函数 功能
getuid |
获取用户标识号,获取当前进程的有效用户标识号。 |
setuid |
设置用户标志号,设置当前进程的有效用户标识号。 |
getgid |
获取组标识号,获取当前进程的有效组标识号。 |
setgid |
设置组标志号,设置当前进程的有效组标识号。 |
getegid |
获取有效组标识号,获取当前进程的有效组标识号(与 getgid 功能类似)。 |
setegid |
设置有效组标识号,设置当前进程的有效组标识号。 |
geteuid |
获取有效用户标识号,获取当前进程的有效用户标识号(与 getuid 功能类似)。 |
seteuid |
设置有效用户标识号 |
setregid |
分别设置真实和有效的组标识号 |
setreuid |
分别设置真实和有效的用户标识号 |
getresgid |
分别获取真实的、有效的和保存过的组标识号 |
setresgid |
分别设置真实的、有效的和保存过的组标识号 |
getresuid |
分别获取真实的、有效的和保存过的用户标识号 |
setresuid |
分别设置真实的、有效的和保存过的用户标识号 |
setfsgid |
设置文件系统检查时使用的组标识号 |
setfsuid |
设置文件系统检查时使用的用户标识号 |
getgroups |
获取后补组标志清单 |
setgroups |
设置后补组标志清单 |
(九)进程间通信函数
函数 功能
ipc |
进程间通信总控制调用,可用于对 System V 风格的进程间通信对象(如消息队列、共享内存、信号量)进行创建、删除、获取属性等操作。通过不同的命令参数来指定具体的操作类型,例如创建消息队列、获取共享内存的状态等。 |
(十)信号相关函数
信号相关函数用于处理进程接收到的信号,包括设置信号处理方式、阻塞信号、发送信号等操作:
函数 功能
sigaction |
设置对指定信号的处理方法,允许程序员指定信号的处理函数、信号处理时的选项等。与传统的signal函数相比,sigaction提供了更丰富和灵活的信号处理机制。 |
sigprocmask |
根据参数对信号集中的信号执行阻塞/解除阻塞等操作。可以通过该函数来控制进程对特定信号的响应,例如阻塞某些信号以避免在特定操作期间被中断,或者解除对信号的阻塞以允许其正常处理。 |
sigpending |
为指定的被阻塞信号设置队列,用于获取当前进程中被阻塞且尚未处理的信号集合。进程可以通过检查这个信号队列来了解有哪些信号被暂时阻塞,以及在合适的时候处理这些信号。 |
sigsuspend |
挂起进程等待特定信号,该函数会使进程进入挂起状态,直到接收到一个未被阻塞的信号。在接收到信号后,进程会执行相应的信号处理函数,然后 sigsuspend返回。 |
signal |
早期用于设置信号处理函数的函数,指定当接收到特定信号时要执行的操作,可以是默认操作、忽略信号或者自定义的信号处理函数。不过,signal函数在某些情况下可能存在一些不可靠的行为,因此在新的代码中更推荐使用sigaction。 |
kill |
向进程或进程组发信号,用于向指定的进程或进程组发送一个信号。可以通过该函数来通知进程执行某些操作,例如终止进程(发送SIGTERM信号)、暂停进程(发送SIGSTOP信号)等。 |
*sigblock |
向被阻塞信号掩码中添加信号,已被sigprocmask代替。在早期的 Linux 版本中,sigblock用于将指定的信号添加到进程的信号阻塞掩码中,但现在更建议使用功能更强大和灵活的sigprocmask函数。 |
*siggetmask |
取得现有阻塞信号掩码,已被sigprocmask代替。该函数用于获取进程当前的信号阻塞掩码,现在同样可以通过sigprocmask函数来实现这一功能。 |
*sigsetmask |
用给定信号掩码替换现有阻塞信号掩码,已被sigprocmask代替。它的功能是将进程的信号阻塞掩码设置为指定的信号掩码,现在sigprocmask函数提供了更全面的信号掩码操作功能。 |
*sigmask |
将给定的信号转化为掩码,已被sigprocmask代替。该函数的作用是将一个或多个信号转换为信号掩码,以便用于信号阻塞等操作,现在也由sigprocmask函数替代。 |
*sigpause |
作用同sigsuspend,已被sigsuspend代替。sigpause函数用于挂起进程并等待信号,与sigsuspend函数的功能类似,但现在更推荐使用sigsuspend。 |
sigvec |
为兼容 BSD 而设的信号处理函数,作用类似sigaction。在一些需要兼容 BSD 系统的代码中可能会用到sigvec,它提供了与sigaction类似的信号处理功能,用于设置信号的处理方式。 |
ssetmask |
ANSI C 的信号处理函数,作用类似sigaction。ssetmask是 ANSI C 标准中提供的用于处理信号的函数,其功能与sigaction类似,用于设置信号的处理函数和相关选项。 |
(十一)消息相关函数
消息相关函数用于操作消息队列,实现进程间的消息传递:
函数 功能
msgctl |
消息控制操作,可用于对消息队列进行各种控制操作,如获取消息队列的属性、设置消息队列的属性、删除消息队列等。通过不同的命令参数来指定具体的操作,例如IPC_STAT用于获取消息队列的状态信息,IPC_RMID用于删除消息队列。 |
msgget |
获取消息队列,创建一个新的消息队列或获取已存在的消息队列的标识符。可以指定消息队列的键值和权限等参数,键值用于唯一标识一个消息队列。 |
msgsnd |
发消息,向指定的消息队列中发送一条消息。消息由消息类型和消息数据组成,发送时需要指定消息队列的标识符、消息内容以及相关的标志位。 |
msgrcv |
取消息,从指定的消息队列中接收一条消息。可以指定接收消息的队列标识符、消息缓冲区、消息大小、期望的消息类型以及相关的标志位,根据指定的条件从消息队列中获取消息。 |
(十二)管道相关函数
函数 功能
pipe |
创建管道,用于创建一个匿名管道,返回两个文件描述符,一个用于读(fd[0]),一个用于写(fd[1])。匿名管道是一种半双工的通信方式,通常用于具有亲缘关系的进程间通信,如父子进程。 |
(十三)信号量相关函数
信号量相关函数用于操作信号量集,实现进程间的同步和互斥:
函数 功能
semctl |
信号量控制,可用于对信号量集进行各种控制操作,如获取信号量集的属性、设置信号量的值、删除信号量集等。通过不同的命令参数来指定具体的操作,例如GETVAL用于获取信号量的值,IPC_RMID用于删除信号量集。 |
semget |
获取一组信号量,创建一个新的信号量集或获取已存在的信号量集的标识符。可以指定信号量集的键值、信号量的数量和权限等参数,键值用于唯一标识一个信号量集。 |
semop |
信号量操作,对信号量集中的信号量进行操作,如增加或减少信号量的值。操作时需要指定信号量集的标识符、操作数组(包含对每个信号量的操作信息)以及相关的标志位,通过这些操作来实现进程间的同步和互斥。 |
(十四)共享内存相关函数
共享内存相关函数用于操作共享内存,实现进程间高效的数据共享:
函数 功能
shmctl |
控制共享内存,可用于对共享内存进行各种控制操作,如获取共享内存的属性、设置共享内存的属性、删除共享内存等。通过不同的命令参数来指定具体的操作,例如IPC_STAT用于获取共享内存的状态信息,IPC_RMID用于删除共享内存。 |
shmget |
获取共享内存,创建一个新的共享内存段或获取已存在的共享内存段的标识符。可以指定共享内存的键值、大小和权限等参数,键值用于唯一标识一个共享内存段。 |
shmat |
连接共享内存,将共享内存段附加到当前进程的地址空间中,使得进程可以访问共享内存中的数据。返回共享内存段在进程地址空间中的起始地址。 |
shmdt |
拆卸共享内存,将共享内存段从当前进程的地址空间中分离,释放与共享内存段相关的资源。在不再使用共享内存时,需要调用该函数来断开与共享内存的连接。 |
十二、fork 函数
fork 是 Linux 系统中用于创建子进程的函数,它的特别之处在于一次调用,两次返回。当父进程调用 fork 时,内核会创建一个新的子进程,这个子进程是父进程的一个副本,它与父进程共享部分资源(如代码段、数据段的某些部分等),但也有自己独立的一些资源(如进程 ID 等)。fork 函数的返回值用于区分父进程和子进程:
pid_t child = fork();
if( child < 0 ) { //fork error.
perror("fork process fail.
");
} else if( child ==0 ) { // in child process
printf(" fork succ, this run in child process
");
} else { // in parent process
printf(" this run in parent process
");
}
在上述代码中,fork 函数调用后,父进程会返回子进程的 ID(一个大于 0 的整数),而子进程会返回 0。如果 fork 调用失败,会返回一个小于 0 的值,并设置相应的错误号。通过检查 fork 的返回值,父进程和子进程可以执行不同的代码逻辑。
十三、僵尸进程
僵尸进程是指子进程已经结束运行,但父进程尚未调用 wait 或 waitpid 来获取子进程的退出状态信息,此时子进程的进程描述符仍然保留在系统中,处于一种特殊的状态。
(一)僵尸进程产生原因
一个进程使用 fork 创建子进程后,子进程在完成其任务后会退出。正常情况下,父进程应该调用 wait 或 waitpid 函数来获取子进程的退出状态,释放子进程占用的资源。但如果父进程没有这样做,子进程就会变成僵尸进程。僵尸进程会占用系统的进程表项资源,如果大量产生,可能会导致系统资源耗尽。
(二)僵尸进程解决办法
通过信号机制:子进程退出时,系统会向父进程发送 SIGCHILD 信号。父进程可以通过注册信号处理函数来处理 SIGCHILD 信号,在信号处理函数中调用 wait 或 waitpid 来回收子进程的资源,从而避免僵尸进程的产生。例如:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
void sig_child(int signo) {
pid_t pid;
int stat;
while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
printf("child %d terminated
", pid);
}
return;
}
int main() {
struct sigaction sa;
sa.sa_handler = sig_child;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGCHLD, &sa, NULL) < 0) {
perror("sigaction error");
exit(1);
}
// 创建子进程
pid_t child_pid = fork();
if (child_pid < 0) {
perror("fork error");
exit(1);
} else if (child_pid == 0) {
// 子进程执行的代码
printf("I am child process, pid = %d
", getpid());
exit(0);
} else {
// 父进程执行的代码
printf("I am parent process, pid = %d
", getpid());
while (1) {
// 父进程做其他事情
sleep(1);
}
}
return 0;
}
fork 两次:父进程首先创建子进程 A,子进程 A 再创建子进程 B,然后子进程 A 退出。这样,子进程 B 就会被 init 进程(进程 ID 为 1)接管。init 进程会自动处理子进程 B 的退出,回收其资源,从而避免子进程 B 成为僵尸进程。
(三)ps 指令查看僵尸进程
可以使用 ps 指令结合 grep 命令来查看系统中的僵尸进程,命令如下:
ps -A -ostat,pid,cmd |grep -iE '^z'
其中,-A 选项表示显示所有任务;-o 选项按照指定格式输出,这里指定输出进程的状态(stat)、进程 ID(pid)和命令(cmd);grep -iE '^z' 用于筛选出状态以 z 开头的行,在 ps 输出中,僵尸进程的状态通常以 Z 开头(不区分大小写)。
十四、常见文件说明
在 Linux 系统中,有许多重要的文件用于记录系统的各种信息,以下是一些常见文件的说明:
/var/log/boot.log:系统引导日志,记录了系统在引导过程中发生的事件和信息,如内核加载过程、硬件检测信息等。通过查看这个文件,可以了解系统启动时是否存在问题。
/var/log/dmesg:系统核心启动日志,包含了内核在启动和运行过程中输出的消息,如设备驱动的加载信息、硬件错误信息等。dmesg 命令可以用于查看这些消息。
/var/log/messages:核心系统日志,记录了系统的各种核心事件和错误信息,如系统服务的启动和停止、硬件故障等。它是系统管理员排查系统问题的重要参考文件。
/var/log/maillog:邮件系统日志,记录了邮件服务器的活动,如邮件的发送、接收、错误信息等。对于邮件系统的管理和维护非常重要。
/var/log/xferlog:FTP 系统日志,记录了 FTP 服务器的文件传输活动,包括用户的登录、文件的上传和下载等信息。
/var/log/syslog:系统出问题的日志,记录了系统中发生的各种错误、警告和其他重要事件,涵盖了多个系统组件和服务的信息。
/var/log/secure:安全信息和系统登录与网络连接的信息,记录了用户的登录尝试、认证成功或失败的信息,以及网络连接的相关安全事件。
/var/log/wtmp:登录记录,记录了所有用户的登录和注销信息,包括登录时间、注销时间、登录终端等。可以使用 last 命令来查看这个文件的内容。
/var/spool/clientmqueue:邮件队列目录,用于存储待发送的邮件队列。当邮件服务器发送邮件时,邮件会先存储在这里,然后再进行发送。
/proc/interrupts:记录了系统中每个 IRQ(中断请求)的中断数,用于了解系统中硬件设备的中断情况,对于调试硬件问题和性能优化有一定的帮助。
/etc/fstab:Linux 内核引导时,会从文件 /etc/fstab 中读取要加载的文件系统信息。该文件包含了文件系统的设备名称、挂载点、文件系统类型、挂载选项等信息,用于自动挂载文件系统。
十五、proc 目录说明
proc 文件系统是 Linux 系统中的一个特殊的伪文件系统,它只存在于内存当中,用于提供系统和进程的相关信息。通过访问 proc 目录下的文件和子目录,可以获取各种系统状态和进程信息:
系统整体信息文件:
/proc/buddyinfo:每个内存区中的每个 order 有多少块可用,和内存碎片问题有关。通过查看这个文件,可以了解系统内存的分配和碎片化情况。
/proc/cmdline:启动时传递给 kernel 的参数信息,记录了系统启动时内核所接收到的命令行参数。
/proc/cpuinfo:cpu 的信息,包含了 CPU 的型号、频率、缓存大小等详细信息。
/proc/crypto:内核使用的所有已安装的加密密码及细节,用于了解系统中加密算法的使用情况。
/proc/devices:已经加载的设备并分类,列出了系统中已加载的各种设备,按照设备类型进行分类。
/proc/dma:已注册使用的 ISA DMA 频道列表,记录了系统中使用 DMA(直接内存访问)的设备和频道信息。
/proc/execdomains:Linux 内核当前支持的 execution domains,表示系统支持的不同执行环境。
/proc/fb:帧缓冲设备列表,包括数量和控制它的驱动,用于了解系统中帧缓冲设备的信息,如显卡的帧缓冲区设置。
/proc/filesystems:内核当前支持的文件系统类型,列出了系统内核支持的所有文件系统类型。
/proc/interrupts:x86 架构中的每个 IRQ 中断数,记录了系统中各个中断请求的发生次数。
/proc/iomem:每个物理设备当前在系统内存中的映射,显示了物理设备在内存中的地址映射关系。
/proc/ioports:一个设备的输入输出所使用的注册端口范围,记录了设备所使用的 I/O 端口信息。
/proc/kcore:代表系统的物理内存,存储为核心文件格式,里边显示的是字节数,等于 RAM 大小加上 4kb
/proc/kmsg:记录内核生成的信息,可以通过 /sbin/klogd 或 /bin/dmesg 来处理。这些信息包含了内核在运行过程中的各种状态和错误消息,对系统调试和故障排查很有帮助。
/proc/loadavg:根据过去一段时间内 CPU 和 IO 的状态得出的负载状态,与 uptime 命令有关。它显示了系统在 1 分钟、5 分钟、15 分钟内的平均负载情况,反映了系统的繁忙程度。
/proc/locks:内核锁住的文件列表,列出了当前被内核锁定的文件,可用于分析文件访问的并发控制情况。
/proc/mdstat:多硬盘,RAID 配置信息(md=multiple disks),显示了系统中 RAID 设备的状态和配置信息,如 RAID 级别、成员盘状态等。
/proc/meminfo:RAM 使用的相关信息,包含了系统内存的详细统计数据,如总内存、已用内存、空闲内存、缓冲区内存等。
/proc/misc:其他的主要设备(设备号为 10)上注册的驱动,记录了一些特殊设备的驱动信息。
/proc/modules:所有加载到内核的模块列表,列出了当前系统中已加载的内核模块及其相关信息,如模块名称、大小、使用情况等。
/proc/mounts:系统中使用的所有挂载,显示了当前系统中已挂载的文件系统及其挂载点等信息。
/proc/mtrr:系统使用的 Memory Type Range Registers(MTRRs),记录了系统中内存类型范围寄存器的设置信息,用于管理内存的访问。
/proc/partitions:分区中的块分配信息,显示了系统中磁盘分区的相关信息,如分区大小、已使用块数等。
/proc/pci:系统中的 PCI 设备列表,列出了系统中所有 PCI 设备的详细信息,如设备厂商、设备 ID、设备功能等。
/proc/slabinfo:系统中所有活动的 slab 缓存信息,slab 缓存是内核用于管理内存分配的一种机制,此文件显示了 slab 缓存的使用情况和统计信息。
/proc/stat:所有的 CPU 活动信息,包含了 CPU 的各种统计数据,如用户态时间、系统态时间、空闲时间等,可用于分析 CPU 的使用情况。
/proc/sysrq-trigger:使用 echo 命令来写这个文件的时候,远程 root 用户可以执行大多数的系统请求关键命令,就好像在本地终端执行一样。要写入这个文件,需要把 /proc/sys/kernel/sysrq 不能设置为 0。这个文件对 root 也是不可读的,主要用于在特殊情况下对系统进行紧急操作。
/proc/uptime:系统已经运行了多久,显示了系统自启动以来的运行时间,以秒为单位。
/proc/swaps:交换空间的使用情况,显示了系统中交换分区(swap)的使用情况,如交换分区的大小、已使用空间、空闲空间等。
/proc/version:Linux 内核版本和 gcc 版本,记录了当前系统所使用的 Linux 内核版本以及编译内核时使用的 gcc 版本信息。
/proc/bus:系统总线(Bus)信息,例如 pci/usb 等,该目录下包含了与系统总线相关的子目录,用于存储总线设备的信息。
/proc/driver:驱动信息,包含了系统中各种设备驱动的相关信息,可用于查看驱动的状态和配置。
/proc/fs:文件系统信息,包含了与系统文件系统相关的子目录和信息,用于了解文件系统的状态和配置。
/proc/ide:ide 设备信息,列出了系统中 IDE 设备的相关信息,如硬盘、光驱等设备的参数和状态。
/proc/irq:中断请求设备信息,进一步详细记录了系统中中断请求设备的相关信息,有助于分析中断相关的问题。
/proc/net:网卡设备信息,该目录下包含了与网络设备相关的子目录和文件,用于查看网络设备的状态、配置和统计信息。
/proc/scsi:scsi 设备信息,列出了系统中 SCSI 设备的详细信息,如 SCSI 硬盘、磁带机等设备的参数和状态。
/proc/tty:tty 设备信息,包含了系统中 tty 设备(如终端设备)的相关信息,如设备名称、状态等。
/proc/net/dev:显示网络适配器及统计信息,提供了每个网络接口的详细统计数据,如接收和发送的字节数、数据包数、错误数等。
/proc/vmstat:虚拟内存统计信息,包含了虚拟内存系统的各种统计数据,如页面交换、内存分配和回收等信息,对分析虚拟内存的性能很有帮助。
/proc/vmcore:内核 panic 时的内存映像,当系统发生内核 panic(严重错误导致内核崩溃)时,会生成这个内存映像文件,用于调试和分析内核崩溃的原因。
/proc/diskstats:取得磁盘信息,显示了系统中磁盘设备的统计信息,如磁盘的读写次数、读写字节数、平均读写时间等。
/proc/schedstat:kernel 调度器的统计信息,包含了内核调度器的各种统计数据,如进程的调度次数、运行时间等,可用于分析进程调度的性能。
/proc/zoneinfo:显示内存空间的统计信息,对分析虚拟内存行为很有用,提供了系统中内存区域(zone)的详细统计数据,如内存分配、回收和管理情况。
以下是 /proc 目录中进程 N 的信息
/proc/N:pid 为 N 的进程信息,该目录下包含了与进程 N 相关的各种文件和子目录,用于存储进程的详细信息。
/proc/N/cmdline:进程启动命令,显示了启动该进程时使用的命令行参数,有助于了解进程的启动方式和配置。
/proc/N/cwd:链接到进程当前工作目录,是一个符号链接,指向进程的当前工作目录,通过这个链接可以快速定位进程的工作目录。
/proc/N/environ:进程环境变量列表,列出了进程的环境变量,包含了进程运行时所需的各种环境信息,如路径、语言设置等。
/proc/N/exe:链接到进程的执行命令文件,是一个符号链接,指向进程的可执行文件,可用于查看进程对应的可执行文件路径。
/proc/N/fd:包含进程相关的所有的文件描述符,该目录下的每个文件都是一个符号链接,指向进程打开的文件或设备,通过这些链接可以了解进程所使用的文件和设备资源。
/proc/N/maps:与进程相关的内存映射信息,显示了进程的内存映射情况,包括进程使用的内存区域、内存权限、映射的文件等信息,对分析进程的内存使用很有帮助。
/proc/N/mem:指代进程持有的内存,不可读,虽然不能直接读取其内容,但它代表了进程所占用的内存区域。
/proc/N/root:链接到进程的根目录,是一个符号链接,指向进程的根目录,对于一些使用了 chroot 机制的进程,这个链接可以显示其虚拟根目录。
/proc/N/stat:进程的状态,包含了进程的各种状态信息,如进程 ID、父进程 ID、状态标志、CPU 时间等,可用于了解进程的运行状态。
/proc/N/statm:进程使用的内存的状态,提供了进程内存使用的统计信息,如进程占用的总内存、共享内存、代码段大小等。
/proc/N/status:进程状态信息,比 stat/statm 更具可读性,以更直观的方式显示了进程的状态信息,包括进程的基本信息、内存使用情况、调度信息等。
/proc/self:链接到当前正在运行的进程,是一个符号链接,指向当前进程的 /proc 目录下的进程信息,方便进程自身获取其相关信息。
十六、fopen 参数说明
fopen 是 C 语言中用于打开文件的函数,它的参数决定了文件的打开方式和属性。以下是对 fopen 参数的详细说明:
参数 说明
r |
以只读方式打开文件,该文件必须存在。如果文件不存在,fopen 函数将返回 NULL。文件指针会指向文件的开头。 |
r+ |
以可读写方式打开文件,该文件必须存在。文件指针指向文件的开头,可以对文件进行读取和写入操作。 |
rb+ |
读写打开一个二进制文件,允许读写数据,文件必须存在。用于处理二进制文件,文件指针指向文件开头。 |
w |
打开只写文件,若文件存在则文件长度清为 0,即该文件内容会消失。若文件不存在则建立该文件。文件指针指向文件开头。 |
w+ |
打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。文件指针指向文件开头,可进行读写操作。 |
a |
以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF 符保留)文件指针指向文件末尾。 |
a+ |
以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的 EOF 符不保留)文件指针指向文件末尾,可进行读写操作,但读取时需注意指针位置。 |
wb |
只写打开或新建一个二进制文件;只允许写数据。用于创建或打开二进制文件进行写入操作,若文件存在则覆盖原有内容。 |
wb+ |
读写打开或建立一个二进制文件,允许读和写。可对二进制文件进行读写操作,若文件存在则打开,不存在则创建。 |
ab+ |
读写打开一个二进制文件,允许读或在文件末追加数据。用于处理二进制文件,可在文件末尾追加数据,也可进行读取操作。 |
wx |
创建文本文件,只允许写入数据.[C11] 若文件已存在或者无法创建(一般是路径不正确)都会导致 fopen 失败。文件以操作系统支持的独占模式打开。 |
wbx |
创建一个二进制文件,只允许写入数据.[C11] 若文件已存在则 fopen 失败,以独占模式创建二进制文件进行写入。 |
w+x |
创建一个文本文件,允许读写.[C11] 若文件已存在则 fopen 失败,创建文本文件并可进行读写操作。 |
wb+x |
创建一个二进制文件,允许读写.[C11] 若文件已存在则 fopen 失败,创建二进制文件并可进行读写操作。 |
w+bx |
和 “wb+x” 相同[C11] 功能与 wb+x 一致,用于创建可读写的二进制文件。 |
以
x结尾的模式为独占模式,文件已存在或者无法创建(一般是路径不正确)都会导致fopen失败.文件以操作系统支持的独占模式打开.[C11] 这些参数的选择根据具体的文件操作需求来确定,正确使用参数可以确保文件操作的准确性和可靠性。


















暂无评论内容