还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
进程控制UNIX欢迎来到UNIX进程控制课程本课程将深入探讨操作系统的核心概念,特别是UNIX/Linux系统中的进程管理与控制机制我们将从理论基础出发,逐步深入到实际应用层面进程是现代操作系统中最基本也是最重要的概念之一,它是系统资源分配的基本单位,也是程序执行的载体通过本课程,您将全面了解UNIX系统中进程的创建、终止、通信、调度等核心机制,以及相关的系统调用接口无论您是系统程序员、应用开发者还是对操作系统原理感兴趣的学习者,本课程都将为您提供宝贵的知识与实践经验让我们一起探索UNIX进程控制的奥秘!课程概述进程基础概念与理论探讨进程的定义、特性以及UNIX进程模型的核心理论基础进程创建与终止学习fork、exec系统调用及进程终止机制进程通信与同步掌握管道、信号、共享内存等IPC机制进程调度与管理了解调度算法、优先级控制及资源限制技术实际应用与案例分析通过实例讲解进程控制在系统开发中的应用第一部分进程基础概念什么是进程探究进程的本质定义及其在操作系统中的角色,理解进程作为资源分配和调度的基本单位的重要性进程与程序的区别分析进程作为动态执行实体与程序作为静态代码集合之间的根本差异进程状态与生命周期详解进程从创建到终止的各个状态及转换机制进程模型特点UNIX了解UNIX系统独特的进程管理模型及其设计哲学进程的定义程序的执行实例进程是程序代码被加载到内存中并处于运行状态的动态实例一个静态的程序文件可以产生多个执行中的进程实例,每个实例都有自己独立的执行路径和状态独立的地址空间每个进程都拥有自己的虚拟地址空间,包括代码段、数据段、堆、栈等区域这种隔离确保了进程间的独立性和安全性,防止一个进程意外修改另一个进程的数据资源分配的基本单位操作系统以进程为单位分配和管理系统资源,包括CPU时间、内存空间、文件描述符等进程控制块PCB记录了进程所拥有的所有资源信息基本特性进程具有动态性随时间变化状态、并发性多个进程可以并发执行、独立性进程间相互独立等核心特性,这些特性构成了现代操作系统的基础进程与程序的区别程序进程程序是存储在磁盘或其他存储介质上的静态实体,由代码和数据进程是程序的一次执行活动,是动态的、活跃的实体它在内存组成,是一组指令的集合它是被动的、静止的,不消耗CPU资中占用空间,消耗CPU和其他系统资源,具有自己的生命周期源,也不占用运行时内存程序本身不执行任何操作,需要被加载到内存并由CPU执行才能一个进程包含程序计数器、寄存器值、变量当前值、打开的文件发挥作用程序可以被多次执行,每次执行都可能创建一个新的等运行状态信息同一程序的不同进程可能有完全不同的执行路进程径和状态示例存储在磁盘上的可执行文件,如/bin/ls命令文件多个进程可以执行同一个程序,如多个用户同时运行同一个浏览器程序,每个实例都是独立的进程进程状态UNIX睡眠态阻塞态/Sleeping/Blocked进程正在等待某个事件发生或资就绪态Ready源变为可用,如IO操作完成、信僵尸态Zombie进程已准备好运行,只等待CPU号到达等此状态下进程不会被分配时间片所有就绪态进程形调度执行进程已终止,但其父进程尚未调成就绪队列,等待调度器选择用wait回收其资源此时进程运行态Running的PCB仍保留在系统中进程正在CPU上执行,或者在多停止态Stopped处理器系统中的某个CPU上执行在任何时刻,单核CPU上只进程执行被暂停,通常由信号如能有一个进程处于此状态SIGSTOP引起可以稍后恢复执行SIGCONT进程状态转换创建就绪→进程被创建后,系统为其分配PCB和必要资源,初始化完成后进入就绪态,等待CPU调度就绪运行→调度器根据调度算法选择一个就绪进程,分配CPU时间片,进程开始执行这个转换称为进程调度dispatch运行就绪→进程时间片用完被抢占,或优先级更高的进程到达进程被迫释放CPU但仍保持就绪状态,等待下次调度运行阻塞→进程执行I/O操作或等待某个事件,主动放弃CPU并进入阻塞状态只有当等待的条件满足后才能再次变为就绪阻塞就绪→进程等待的事件发生如I/O完成、信号到达,阻塞条件解除,进程变为就绪态,等待再次被调度进程控制块PCB标识信息进程IDPID、父进程IDPPID、用户IDUID、组IDGID状态信息当前进程状态、优先级、调度相关信息控制信息程序计数器、寄存器值、堆栈指针内存管理信息内存段表、页表、内存限制资源管理打开文件表、信号处理表、IPC资源进程层次结构UNIX进程init PID1系统启动时创建的第一个用户进程系统守护进程提供系统服务的后台进程用户进程用户创建的应用程序进程UNIX系统采用树状的进程层次结构,每个进程init除外都有一个父进程,可以有零个或多个子进程当系统启动时,首先创建init进程,它是所有用户态进程的祖先这种层次结构带来了管理上的便利父进程可以控制子进程的创建和终止,同时系统可以按层次清理进程资源进程组和会话概念也基于这种结构,使得shell可以有效管理相关进程集合使用pstree命令可以直观地查看系统进程树结构,了解进程间的父子关系这种设计是UNIX系统的特色之一,体现了其简洁而优雅的设计理念第二部分进程创建写时复制技术进程复制原理深入理解Copy-on-Write优化技函数族exec探索UNIX系统如何实现进程复术如何提高fork效率,减少不系统调用fork掌握如何通过exec家族函数替制,包括地址空间复制、文件描必要的内存复制,节约系统资学习如何通过fork创建新进换进程映像,实现程序切换了述符继承等底层机制源程,理解其一次调用,两次返回解不同版本exec函数的参数差异的特性,以及父子进程的关系和及适用场景数据共享机制系统调用fork基本功能返回值特性fork是UNIX系统中创建新进程的主要方法它通过复制调用进程父进程fork的一个独特之处在于一次调用,两次返回在父进程中,fork返回来创建一个新进程子进程子进程获得父进程数据空间、堆、栈等的副新创建子进程的PID;在子进程中,fork返回0这允许代码区分自己是父本,但有自己独立的地址空间进程还是子进程子进程继承父进程的大部分属性,包括打开的文件描述符、信号处理设置、如果fork调用失败如系统资源不足,则在父进程中返回-1,并设置工作目录、资源限制等但子进程有自己的进程ID,且父进程ID设置为创建errno利用这种返回值机制,程序可以在fork之后让父子进程执行不同的它的进程代码路径pid_t pid=fork;if pid0{//错误处理}else if pid==0{//子进程代码}else{//父进程代码}执行流程fork复制进程地址空间系统为子进程创建与父进程相同的地址空间副本,包括代码段、数据段、堆和栈复制进程控制块创建新的PCB,继承父进程的大部分属性,如文件描述符、环境变量等分配新的PID为子进程分配唯一的进程ID,设置其父进程ID为创建它的进程ID添加到进程表将新进程添加到系统进程表中,设置为就绪状态等待调度执行#include#includeint main{pid_t pid;int x=1;pid=fork;if pid0{fprintfstderr,Fork failed\n;return1;}else ifpid==0{//子进程printf子进程:x=%d\n,++x;}else{//父进程printf父进程:x=%d\n,--x;}return0;}写时复制Copy-on-Write02内存页共享相关进程fork初始时,父子进程实际共享物理内存页仅父子两个进程参与COW机制90%效率提升大多数情况下可显著减少内存使用写时复制Copy-on-Write是一种重要的内存优化技术,特别适用于fork操作传统fork会立即复制父进程的整个地址空间,这在进程内存较大时非常低效,尤其是许多fork调用后立即执行exec的情况COW技术延迟了实际的物理内存复制操作fork后,子进程最初只获得父进程页表的副本,而实际物理页面仍由父子进程共享同时,这些共享页面被标记为只读只有当任一进程尝试修改共享页面内容时,内核才会为修改进程创建该页面的私有副本,实现真正的复制这种优化对于shell这类频繁使用fork+exec模式的程序尤为重要,因为大多数情况下,子进程在执行新程序前几乎不修改从父进程继承的内存内容,从而避免了不必要的内存复制开销函数族exec函数名参数传递方式路径搜索环境变量execl列表形式需完整路径使用当前环境execlp列表形式搜索PATH使用当前环境execle列表形式需完整路径可指定环境execv向量形式需完整路径使用当前环境execvp向量形式搜索PATH使用当前环境execve向量形式需完整路径可指定环境exec函数族的主要功能是在当前进程中执行一个新程序,完全替换当前进程的代码和数据调用成功后,新程序从其main函数开始执行,而原进程的内存空间被新程序覆盖这些函数的核心区别在于参数传递方式和环境设置带l的使用参数列表list,带v的使用参数向量vector;带p的会搜索PATH环境变量查找可执行文件,带e的允许显式指定新程序的环境变量实际应用execshell命令执行模型当用户在shell中输入命令,shell首先fork创建子进程,然后子进程通过exec加载并执行指定的命令程序父进程shell通常通过wait等待子进程完成这种fork+exec组合是UNIX系统命令执行的标准模式典型代码模式在系统编程中,创建新进程执行其他程序的标准方法是先调用fork创建子进程,然后在子进程中调用exec系列函数之一这种组合使得子进程可以在执行新程序前进行必要的环境准备使用示例与注意事项exec调用成功后永不返回,因为进程已被新程序替换如果exec返回,说明调用失败,应进行错误处理exec后,进程ID保持不变,只是进程内容被替换文件描述符通常会被继承,除非设置了FD_CLOEXEC标志位#include#include#includeint main{pid_t pid=fork;ifpid0{perrorfork failed;exit1;}else ifpid==0{//子进程执行ls命令execl/bin/ls,ls,-l,NULL;//如果execl返回,说明出错了perrorexecl failed;exit1;}else{//父进程等待子进程结束waitNULL;printf子进程已完成\n;}return0;}进程终止正常终止方式•从main函数返回•调用exit函数•调用_exit或_Exit系统调用•最后一个线程从其启动例程返回异常终止方式•接收到未处理的信号如SIGKILL•出现严重错误如段错误•被其他进程终止与区别exit_exitexit是标准C库函数,会执行清理操作,如刷新I/O缓冲区、调用已注册的退出处理函数atexit等;而_exit是系统调用,直接让内核终止进程,不执行任何清理操作退出状态码进程终止时向父进程返回一个0-255之间的退出码按惯例,0表示成功,非0表示出错特定退出码的含义由程序自行定义,但通常遵循一些常见约定进程等待基本功能与目的与区别wait waitpid父进程通过wait和waitpid系统调用等待子进程终止,并回收wait阻塞调用进程直到有任一子进程终止,返回第一个终止的其资源这些调用有两个主要功能一是获取子进程的终止状子进程ID例如:态,二是防止子进程成为僵尸进程永久占用系统资源pid_t pid=waitstatus;在UNIX系统中,子进程终止后不会立即消失,而是保留在进程表中直到父进程调用wait或waitpid获取其终止状态,这个过waitpid更加灵活,允许指定等待特定子进程或进程组,还支程称为回收子进程如果父进程不调用这些函数,子进程将一持非阻塞等待选项例如:直保持僵尸状态pid_t pid=waitpidpid,status,options;两者都可以通过status参数返回子进程的详细退出状态,包括正常/异常终止、退出码或终止信号等信息可以使用WIFEXITED、WEXITSTATUS等宏检查这些信息僵尸进程Zombie产生原因子进程终止后,其进程描述符仍保留在内核中,等待父进程调用wait或waitpid获取其终止状态并释放资源如果父进程没有调用这些函数,子进程将成为僵尸进程潜在危害虽然僵尸进程几乎不占用系统资源除了进程表项,但如果数量过多,可能耗尽进程ID,导致系统无法创建新进程僵尸进程通常表明程序设计存在缺陷识别方法在ps命令输出中,僵尸进程状态显示为Z通常还会显示标记这类进程不能被普通的kill命令终止,因为它们实际上已经终止预防与消除正确编程父进程应适时调用wait/waitpid;或使用信号处理程序捕获SIGCHLD信号,在处理函数中调用waitpid;对于不关心子进程状态的情况,可以设置SIG_IGN忽略SIGCHLD信号,系统会自动回收子进程守护进程Daemon特征与定义长期运行于后台的服务进程,无控制终端,通常随系统启动而启动创建步骤脱离控制终端,切换会话,设置工作目录,关闭文件描述符,重定向标准输入输出双重技巧fork通过连续两次fork使守护进程成为init的子进程,避免僵尸进程现代管理方式传统sysvinit与现代systemd对比,服务单元配置与管理守护进程是UNIX/Linux系统的重要组成部分,负责提供各种系统服务与普通进程不同,守护进程通常在系统启动时由init或systemd启动,在后台运行,没有控制终端,可以长期存在于系统中直到系统关闭创建标准守护进程需要遵循一定的步骤fork后退出父进程使子进程被init接管,调用setsid创建新会话,再次fork避免意外获取控制终端,设置安全的文件掩码,更改工作目录通常为/,关闭继承的文件描述符,重定向标准输入输出到/dev/null第三部分进程间通信IPC管道命名管道信号消息队列Pipe FIFOSignal单向数据流,用于相关具有文件系统路径的持软中断机制,用于进程结构化数据传输,支持进程通信久管道控制与通知优先级共享内存信号量最高效的IPC,直接访进程同步与互斥控制机问共享区域制进程间通信IPC是操作系统提供的一组机制,使得不同进程能够交换数据和同步操作由于UNIX/Linux系统中进程地址空间独立隔离,进程间不能直接访问对方的内存,因此需要特殊的IPC机制实现通信不同的IPC机制有各自的特点和适用场景例如,管道简单易用但仅适合单向通信;共享内存提供最高的通信效率但需要额外的同步机制;信号适合简单的通知但难以传递数据在实际应用中,要根据通信需求选择合适的IPC方式管道Pipe创建管道进程分离使用pipe系统调用创建一个匿名管道,获取读写文件通过fork创建子进程,继承管道文件描述符描述符数据传输关闭不用端通过write和read系统调用进行数据交换父进程关闭读端,子进程关闭写端或相反管道是最古老也是最常用的IPC机制之一,提供了一种单向的字节流通信方式在shell中,管道符|就是将一个命令的标准输出连接到另一个命令的标准输入匿名管道使用pipe系统调用创建,返回两个文件描述符,一个用于读取,一个用于写入管道具有固定大小的缓冲区通常为4KB,当缓冲区满时写操作会阻塞,当缓冲区空时读操作会阻塞这种特性使管道自然地提供了进程同步机制需要注意的是,匿名管道只能在具有共同祖先的相关进程之间使用,通常是父子进程或兄弟进程管道是半双工的,要实现双向通信需要创建两个管道命名管道FIFO基本特性创建与使用命名管道FIFO是匿名管道的扩展,最大的区别在于它在文件系统中有一个路径名,可以被任可以通过mkfifo命令或mkfifo系统调用创建命名管道例如意进程访问,而不仅限于具有亲缘关系的进程$mkfifo/tmp/myfifo#命令行创建从功能上看,FIFO与匿名管道类似,也是单向字节流,具有相同的阻塞行为和缓冲区机制但由于它有文件系统入口点,任何具有适当权限的进程都可以打开并使用它,这大大扩展了管道//或在程序中的应用范围#includeFIFO在文件系统中表现为一个特殊文件,类型为p可通过ls-l查看虽然它看起来像一个文mkfifo/tmp/myfifo,0666;//系统调用创建件,但实际上它只是一个数据通道,没有实际存储数据创建后,进程可以像操作普通文件一样打开、读写和关闭FIFO int fd=open/tmp/myfifo,O_WRONLY;//写入端writefd,data,size;closefd;intfd=open/tmp/myfifo,O_RDONLY;//读取端readfd,buffer,size;closefd;FIFO特别适合客户端-服务器模型中无关联进程之间的通信,例如数据库查询、日志收集等应用场景信号基础Signal信号是软中断机制,是UNIX/Linux系统中最古老的IPC形式之一它允许进程或内核通知其他进程发生了特定事件信号通常用于异常处理如段错误、进程控制如终止进程或简单的进程间通信系统定义了多种标准信号,每种都有特定的含义和默认处理方式例如,SIGINT2由Ctrl+C触发,用于中断进程;SIGKILL9用于强制终止进程;SIGSEGV11表示段违规通常是非法内存访问信号通过数字标识,但通常使用符号名称引用它们当进程接收到信号时,可能的反应包括忽略信号某些信号如SIGKILL和SIGSTOP无法忽略、执行默认操作如终止进程或产生核心转储、或执行用户定义的信号处理函数信号处理机制是异步的,可能在程序执行的任何点发生信号处理signal函数传统的信号处理函数注册方法,简单但存在可移植性问题语法为void*signalint sig,void*handlerintint;//简化使用signalSIGINT,my_handler;signal在不同系统实现上可能有不同行为,特别是信号阻塞和处理函数重置方面sigaction系统调用更现代、更可靠的信号处理设置方法,提供了更细粒度的控制,是推荐的做法struct sigactionsa;sa.sa_handler=my_handler;sigemptysetsa.sa_mask;sa.sa_flags=0;sigactionSIGINT,sa,NULL;通过sa_mask可以在处理信号期间阻塞其他信号,sa_flags提供了额外的控制选项信号处理函数设计编写信号处理函数需要特别小心,因为它在异步环境中执行应遵循以下原则•保持简单,尽快返回•只调用异步信号安全的函数•访问全局数据时使用volatile sig_atomic_t类型•避免在处理函数中分配内存可重入函数考虑信号处理函数可能在程序执行的任何点被调用,包括另一个函数正在执行时如果此时正在使用非可重入函数,可能导致数据损坏因此,信号处理器应只调用可重入函数,例如write而非printf信号应用实例进程终止控制使用信号可以安全地终止进程,并允许进程在退出前执行清理操作例如,服务进程通常捕获SIGTERM信号以优雅关闭,关闭文件、释放资源并保存状态而对于无响应的程序,可以发送SIGKILL强制终止//捕获SIGTERM进行优雅关闭void term_handlerint sig{cleanup_resources;save_state;exit0;}定时器实现SIGALRM信号可用于实现超时机制或定期任务alarm函数在指定秒数后发送SIGALRM,而setitimer提供更精细的定时控制这在网络程序、监控应用等场景中非常有用//设置5秒超时alarm5;//在处理函数中处理超时逻辑异步IO通知SIGIO信号可用于实现异步IO,当文件描述符就绪时通知程序,而不是阻塞等待这对于需要处理多个输入源的程序特别有用,如网络服务器进程间简单通信用户定义信号如SIGUSR1和SIGUSR2允许进程发送简单的通知给其他进程虽然不能传输数据,但可以触发预定义的行为,如重新加载配置、切换运行模式等//向PID为1234的进程发送SIGUSR1信号kill1234,SIGUSR1;消息队列消息队列消息队列System VPOSIX传统的UNIX System V IPC机制之一,提供了可靠的消息传递方式,支持更现代的消息队列实现,提供了更简洁的API和额外的功能,如异步通知多种消息类型和优先级消息以离散的数据块形式存在,每个消息包含类和超时控制POSIX队列具有名称类似于/myqueue,可以像文件一型标识和实际数据样打开和关闭主要系统调用包括主要函数包括•msgget创建或访问消息队列•mq_open创建或访问队列•msgsnd向队列发送消息•mq_send发送消息•msgrcv从队列接收消息•mq_receive接收消息•msgctl控制队列属性和操作•mq_close关闭队列•mq_unlink删除队列System V消息队列在系统重启后不会自动删除,需要手动管理,通常使用ipcs和ipcrm命令查看和删除POSIX队列支持通知机制,可以在消息到达时通过信号或线程通知应用程序,避免轮询编译时需要链接rt库-lrt消息队列的优势在于它们支持结构化数据传输,消息具有类型和优先级,可以实现选择性接收它们非常适合客户端-服务器模型,特别是在需要排队和优先级处理的场景然而,对于大量数据传输,共享内存通常是更高效的选择共享内存最高效的IPC直接内存访问,无需数据复制内存区域共享多进程可访问同一物理内存需要同步机制必须解决并发访问问题两套APISystem V与POSIX实现共享内存允许多个进程直接访问同一块物理内存区域,是所有IPC机制中速度最快的,因为数据无需在内核和用户空间之间复制每个进程通过将共享内存段映射到自己的地址空间来访问共享数据System V共享内存使用shmget创建或访问共享内存段,shmat将其附加到进程地址空间,shmdt分离内存段,shmctl控制内存段属性POSIX共享内存则使用shm_open、mmap、munmap和shm_unlink函数,接口更类似于文件操作共享内存最大的挑战是同步问题——多个进程同时访问同一内存区域可能导致数据不一致因此,通常需要结合信号量、互斥锁等同步机制使用共享内存特别适合生产者-消费者模型、数据库缓存、高性能计算等需要频繁大量数据交换的场景信号量Semaphore类型与用途信号量SystemV信号量是用于进程同步的计数器,分为二值信号量取值0或1,类似互传统的UNIX信号量实现,支持信号量集一组信号量使用semget斥锁和计数信号量取值范围更广,用于资源计数主要用于控制对创建或访问信号量集,semop执行Pwait和Vsignal操作,共享资源的访问,防止竞态条件semctl控制信号量属性操作可以是原子的,支持多个信号量的组合操作信号量应用场景POSIX更现代的API,分为命名信号量sem_open/sem_close和匿名信号信号量常用于实现互斥锁保证同一时间只有一个进程访问共享资源、量sem_init/sem_destroy操作函数包括sem_waitP操作和条件变量进程等待特定条件满足、读写锁允许多读单写等同步原sem_postV操作,还支持非阻塞尝试sem_trywait和超时等待语在共享内存、生产者-消费者问题等场景中,信号量是解决同步问sem_timedwait题的关键工具第四部分进程调度1140调度决策调度算法CPU每秒做出上千次进程调度决策历史上研究过的CPU调度算法数量409640时间片长度上下文切换典型Linux系统的时间片长度微秒现代处理器上上下文切换时间微秒进程调度是操作系统核心功能之一,负责决定哪个进程何时获得CPU执行权优秀的调度算法可以最大化系统吞吐量,同时保证响应时间和公平性UNIX/Linux系统的调度策略随着时间不断演进,从简单的先来先服务到复杂的完全公平调度调度涉及多种因素,包括进程优先级、运行时间历史、交互性需求等对于普通进程,系统追求公平分配CPU时间;而对于实时进程,则保证在特定时间内完成任务合理的调度策略对系统整体性能有着决定性影响进程调度基本概念调度目标与权衡进程调度需要平衡多种相互冲突的目标,如最大化CPU利用率、最小化响应时间、确保公平性、避免饥饿现象等针对不同类型的系统如批处理系统、交互系统、实时系统,调度目标的重点可能不同抢占与非抢占非抢占式调度Non-preemptive允许进程运行直至完成或自愿放弃CPU,简单但响应性差;抢占式调度Preemptive允许操作系统在任何时刻中断正在运行的进程,分配CPU给其他进程,提高了系统响应性,但增加了复杂性和上下文切换开销评价指标常用指标包括CPU利用率CPU忙碌的时间百分比、吞吐量单位时间完成的进程数、周转时间从提交到完成的总时间、等待时间进程在就绪队列中的总时间、响应时间从请求到首次响应的时间不同应用场景可能关注不同指标上下文切换成本进程切换需要保存当前进程状态并恢复另一进程状态,包括寄存器值、内存映射等,这个过程称为上下文切换,有明显的CPU开销频繁的上下文切换会导致性能下降,因此调度算法需要在响应性和切换开销之间寻找平衡传统调度算法UNIX早期调度UNIX原始UNIX使用相对简单的时间片轮转Round Robin调度算法,每个进程轮流获得一个固定长度的CPU时间片时间片用完后,进程被移到队列末尾,CPU切换到下一个进程这种方法公平但无法区分进程优先级和类型多级反馈队列后来的UNIX系统采用多级反馈队列Multilevel FeedbackQueue算法,它维护多个优先级队列,新进程从最高优先级开始,用完时间片后降级这种设计偏好短小的交互式进程,惩罚长时间运行的CPU密集型进程,提高了系统响应性基于优先级的调度SVR4和BSD UNIX引入了更复杂的基于优先级的调度,动态调整进程优先级优先级部分基于静态的nice值,部分基于动态因素如CPU使用率和睡眠时间这种方法能更好地平衡交互式进程和批处理进程的需求效率与演进传统UNIX调度器的优点是简单高效,适合当时的计算环境但随着多处理器系统普及、工作负载复杂化,其局限性逐渐显现,尤其是在可扩展性和公平性方面,这推动了现代Linux调度器的发展现代调度器Linux调度器内核On
2.4每次调度需要遍历所有可运行进程,复杂度与进程数成正比,在进程数量多时效率较低调度器早期O
12.6使用两个优先级数组和位图实现常数时间复杂度,显著提高了调度效率,但可能导致交互进程饥饿完全公平调度器CFS,
2.
6.23+基于红黑树的调度器,追求CPU时间的完全公平分配,平衡了吞吐量和交互性,是现代Linux的默认调度器实时调度类RT在CFS之上,Linux支持SCHED_FIFO和SCHED_RR两种实时调度策略,保证实时任务的确定性值与进程优先级nice优先级反转问题高优先级进程阻塞高优先级进程尝试获取已被低优先级进程占用的资源如互斥锁而被阻塞中优先级进程抢占中优先级进程抢占正在执行的低优先级进程,导致低优先级进程无法释放资源高优先级进程等待高优先级进程被迫等待中优先级进程完成,间接导致优先级顺序颠倒解决方案优先级继承、优先级天花板、资源保护优先级等协议可以防止优先级反转进程亲和性Affinity概念与作用设置与管理CPU亲和性CPU Affinity是指将进程绑定到特定CPU核心上执行的能力在多核处理器系在命令行,可以使用taskset工具设置进程的CPU亲和性统中,这种机制可以提高缓存命中率,减少跨核心调度导致的缓存失效,从而提升性能#将PID为1234的进程绑定到CPU0和1$taskset-pc0,11234亲和性分为两种类型#以特定亲和性启动新进程•软亲和性Soft Affinity系统尽量保持进程在特定CPU上运行,但在必要时仍可迁移$taskset-c2,
3./myprogram•硬亲和性Hard Affinity强制进程只能在指定的CPU上运行,不允许迁移在高性能计算、实时系统、数据库服务器等对延迟敏感的应用中,正确设置CPU亲和性可在程序中,可以使用sched_setaffinity系统调用设置亲和性以带来显著的性能改善#includecpu_set_t mask;CPU_ZEROmask;//清空CPU集合CPU_SET0,mask;//添加CPU0CPU_SET2,mask;//添加CPU2//设置当前进程的亲和性sched_setaffinity0,sizeofmask,mask;在NUMANon-Uniform MemoryAccess架构中,还需考虑内存节点与CPU核心的亲和性,可使用numactl工具进行管理第五部分进程资源限制内存限制文件限制最大虚拟内存、堆栈大小、数据段大小最大打开文件数、最大文件大小限制CPU最大CPU时间、CPU核心数量限制其他限制进程限制核心转储大小、实时优先级范围最大进程数、最大线程数进程资源限制是操作系统提供的一种控制机制,用于防止单个进程或用户耗尽系统资源这些限制可以保护系统稳定性,避免恶意代码或程序错误导致系统崩溃或资源枯竭在UNIX/Linux系统中,资源限制分为软限制可由进程自身修改,但不能超过硬限制和硬限制只能由root用户降低这种设计既提供了灵活性,又保证了系统安全限制作用于进程及其子进程,因此适合在系统启动脚本或守护进程初始化时设置资源限制机制限制类型说明系统影响RLIMIT_NOFILE最大打开文件描述符数影响并发连接能力RLIMIT_AS最大虚拟内存大小防止内存泄漏耗尽系统RLIMIT_CPU最大CPU时间秒防止CPU密集型程序独占资源RLIMIT_NPROC用户可创建的最大进程数防止fork炸弹等攻击RLIMIT_STACK最大栈空间大小控制递归深度,防止栈溢出RLIMIT_CORE核心转储文件最大大小影响程序崩溃分析能力资源限制是UNIX系统管理的重要组成部分,为系统管理员提供了细粒度的资源控制手段不同的限制类型针对系统的不同方面,例如RLIMIT_NOFILE对于需要处理大量并发连接的网络服务尤为重要,而RLIMIT_NPROC可以有效防止恶意用户通过创建大量进程耗尽系统资源在实际应用中,应根据具体场景设置合适的限制值例如,高性能Web服务器通常需要更高的文件描述符限制,而科学计算程序可能需要更多的虚拟内存和CPU时间资源限制应成为系统配置和应用部署的标准考虑因素,有助于构建更稳定、更安全的系统设置与获取资源限制系统调用接口实际应用示例UNIX/Linux系统提供了getrlimit和setrlimit系统调用来获取和设置资源限制以下是一个增加文件描述符限制的示例#include#include#includestruct rlimit{rlim_t rlim_cur;//软限制int main{rlim_t rlim_max;//硬限制struct rlimitrlim;};//获取当前限制int getrlimitintresource,struct rlimit*rlim;if getrlimitRLIMIT_NOFILE,rlim!=0{int setrlimitintresource,const structrlimit*rlim;perrorgetrlimit failed;return1;}resource参数指定要操作的资源类型如RLIMIT_NOFILE,rlim参数包含软限制和硬限制的值进程可以降低自己的硬限制,但一旦降低就不printf当前文件描述符限制%ld软/%ld硬\n,能再提高;软限制可以在不超过硬限制的情况下随意调整longrlim.rlim_cur,longrlim.rlim_max;//设置新的软限制rlim.rlim_cur=rlim.rlim_max;//将软限制提高到硬限制if setrlimitRLIMIT_NOFILE,rlim!=0{perrorsetrlimit failed;return1;}printf新的文件描述符限制%ld软/%ld硬\n,longrlim.rlim_cur,longrlim.rlim_max;return0;}在命令行shell中,可以使用ulimit命令设置当前shell及其子进程的资源限制例如,设置最大文件描述符数$ulimit-n4096#设置软限制$ulimit-Hn10240#查看硬限制第六部分进程跟踪与调试系统调用工具调试器原理ptrace strace跟踪与控制其他进程执行的跟踪进程的系统调用与信号断点设置、内存检查与进程底层机制控制机制分析工具ltrace、perf等专业进程分析工具进程跟踪与调试技术是系统编程和故障排查的重要工具,允许开发者监视和控制其他进程的执行这些技术通过揭示进程的内部状态、系统调用、信号处理等细节,帮助理解程序行为并诊断问题Linux提供了丰富的跟踪和调试工具,从低级的ptrace系统调用到高级的strace、ltrace、GDB等工具这些工具基于相似的原理,但提供不同层次的抽象和功能熟练使用这些工具对于系统程序员和性能工程师至关重要系统调用ptrace基本功能ptrace是一个强大的系统调用,允许一个进程tracer观察和控制另一个进程tracee的执行,检查和修改其内存和寄存器它是实现调试器、系统调用跟踪器等工具的基础语法:long ptraceenum__ptrace_request request,pid_t pid,void*addr,void*data;主要操作类型•PTRACE_TRACEME:被跟踪进程调用,表示愿意被父进程跟踪•PTRACE_ATTACH:开始跟踪指定PID的进程•PTRACE_DETACH:停止跟踪•PTRACE_PEEKTEXT/PEEKDATA:读取被跟踪进程的内存•PTRACE_POKETEXT/POKEDATA:修改被跟踪进程的内存•PTRACE_GETREGS/SETREGS:获取/设置寄存器值•PTRACE_SYSCALL:使被跟踪进程在每个系统调用前后停止应用场景ptrace通常用于以下场景:•实现调试器,如GDB•跟踪系统调用,如strace•跟踪库调用,如ltrace•实现沙箱和安全监控•进程修改和注入代码限制与注意事项ptrace存在一些重要限制:•一个进程同一时刻只能被一个跟踪者跟踪•需要适当权限通常需要是目标进程的父进程或root权限•跟踪会显著降低目标进程性能•不同平台实现可能有细微差异工具strace基本功能strace是一个强大的诊断工具,用于跟踪进程执行的系统调用和接收的信号它基于ptrace系统调用实现,能够显示系统调用的名称、参数和返回值,帮助理解程序的行为和调试问题常用选项strace提供丰富的命令行选项-f跟踪子进程;-e指定要跟踪的系统调用;-p附加到正在运行的进程;-o将输出写入文件;-c统计系统调用次数和时间;-t/-tt/-ttt显示不同精度的时间戳;-s指定打印的字符串最大长度等性能分析能力除了调试,strace还可用于性能分析-c选项可以生成系统调用统计报告,显示每种调用的次数、平均时间等;-T选项显示每个系统调用的执行时间这些信息有助于识别性能瓶颈,如过多的小型读写操作或低效的文件访问模式实际应用场景strace广泛应用于排查程序无法启动的问题;查找配置文件路径;分析程序的文件和网络访问模式;识别程序使用的系统资源;调查权限问题;分析程序挂起或死锁的原因它是系统管理员和开发者的必备工具之一#跟踪一个新进程$strace ls-l#附加到运行中的进程$strace-p1234#统计系统调用$strace-c command#只跟踪特定系统调用$strace-e open,read,write command#跟踪所有相关进程$strace-f command进程调试GDB附加到运行中进程断点与监视点GDB可以使用attach命令附加到正在运行的进程,这在调试长时间调试的核心功能是设置断点在特定代码位置停止和监视点在特定内运行的服务、分析程序异常行为或debug生产环境问题时特别有用存位置被访问时停止GDB支持多种断点类型普通断点break、条附加后,进程将暂停,允许检查其状态完成后可以使用detach命件断点break ifcondition、临时断点tbreak、硬件断点等监视点令分离,让进程继续运行可以在变量读取rwatch、写入watch或两者awatch时触发多进程调试技术核心转储文件分析GDB支持跟踪fork和exec调用,使用set follow-fork-mode当程序崩溃时,可能会生成核心转储文件core dump,包含程序崩溃child命令可以选择调试子进程而非父进程set detach-on-fork时的完整内存映像GDB可以打开这些文件gdb programcore分析off允许同时调试父子进程,使用info inferiors和inferior N命令在崩溃原因,检查崩溃时的调用栈bt、变量值print和寄存器状态info它们之间切换这对理解复杂的进程创建逻辑非常有价值registers,即使没有源代码也能获取有用信息第七部分线程与进程在UNIX/Linux系统中,线程是进程内的执行单元,共享同一地址空间但有独立的执行路径线程为并发编程提供了比进程更轻量级的机制,因为线程创建和上下文切换的开销显著低于进程这一部分将探讨线程的基本概念、线程与进程的异同、POSIX线程库pthread的使用,以及线程同步的核心技术线程的引入极大地丰富了系统编程模型,特别适合需要共享数据的并发应用,如Web服务器、数据库系统和科学计算不过,线程编程也带来了复杂的同步问题,如竞态条件、死锁和优先级反转掌握线程基础知识对现代系统编程至关重要线程基础线程概念与特性线程标识与生命周期线程Thread是进程内的独立执行流,也被称为轻量级进程LWP每个线程有自己的程每个线程都有一个唯一的线程ID在POSIX线程中为pthread_t类型,用于标识和管理线序计数器、寄存器集合和栈空间,但共享所属进程的代码段、数据段和其他资源如打开的程的生命周期从创建开始,到终止结束,中间可能经历运行、阻塞等状态文件线程可以通过以下方式终止线程的主要特点包括•线程函数正常返回•创建和终止开销比进程小•调用pthread_exit•上下文切换速度更快•被其他线程调用pthread_cancel取消•可以直接访问共享内存,无需IPC•整个进程终止•所有线程共享进程的地址空间线程终止后,其资源不会立即释放,直到被其他线程通过pthread_join回收这类似于•一个线程的崩溃通常会导致整个进程崩溃进程的父进程等待子进程的机制,防止产生僵尸线程//创建线程示例pthread_t tid;pthread_createtid,NULL,thread_function,arg;//等待线程终止pthread_jointid,retval;多线程编程模型一对一模型多对多模型每个用户线程映射到一个内核线程,提供最大并多个用户线程映射到少量内核线程,平衡并行度行度但可能受系统线程数量限制和系统开销实现Linux两级模型现代Linux使用一对一模型,通过NPTLNative结合一对一和多对多的混合模型,灵活性更高POSIX ThreadLibrary实现多线程编程模型定义了用户线程和内核线程之间的映射关系,影响线程的性能、并行度和资源消耗早期UNIX系统使用用户级线程库如GNU Pth,线程调度完全在用户空间进行,内核不感知单个线程的存在这种方法开销小但无法利用多处理器随着多核处理器普及,内核线程支持变得关键Linux线程实现经历了重大演变从早期的LinuxThreads每个线程作为单独进程到现代的NPTLNativePOSIX ThreadLibraryNPTL实现了真正的一对一模型,提供了出色的性能和POSIX兼容性,支持成千上万个线程,是当前Linux系统默认的线程库线程同步互斥锁条件变量mutex conditionvariable最基本的同步机制,确保同一时刻只有一个线程可以访问共享资源用于线程间的通知机制,允许线程等待特定条件满足后再继续执行主要操作包括初始化pthread_mutex_init、加锁通常与互斥锁配合使用,主要操作包括等待pthread_cond_wait、超pthread_mutex_lock、尝试加锁pthread_mutex_trylock、解锁时等待pthread_cond_timedwait、信号通知pthread_mutex_unlock和销毁pthread_mutex_destroy pthread_cond_signal和广播通知pthread_cond_broadcast读写锁屏障rwlock barrier允许多个线程同时读取共享资源,但写入时需要独占访问适合读操一种同步点,要求所有参与线程都到达该点后才能继续执行特别适作远多于写操作的场景,可提高并发性提供读锁定用于需要分阶段同步的并行算法,如矩阵计算主要操作是等待pthread_rwlock_rdlock和写锁定pthread_rwlock_wrlock等操pthread_barrier_wait,当所有线程都调用此函数后,屏障被解除,作,能比互斥锁提供更好的性能所有线程同时继续执行第八部分高级主题进程容器与命名空间Linux命名空间namespace技术允许将系统资源隔离到独立的容器中,每个容器有自己的进程ID、网络、挂载点等视图这是现代容器技术如Docker的基础,提供了轻量级的进程隔离机制资源控制cgroups控制组cgroups是Linux内核的特性,允许对进程组限制、记录和隔离物理资源CPU、内存、I/O等的使用与命名空间结合,构成了完整的容器资源管理解决方案,实现精细的资源分配和限制实时进程特性实时进程需要在严格的时间约束内响应事件,如工业控制、音视频处理等领域Linux提供了SCHED_FIFO和SCHED_RR实时调度策略,以及优先级管理和资源预留机制,满足实时应用需求进程安全与隔离深入探讨seccomp过滤器、AppArmor、SELinux等安全机制,如何限制进程能够执行的系统调用和访问的资源,提高系统安全性,防止恶意代码利用容器技术与进程命名空间Linux进程隔离的基础技术控制组cgroups资源限制与监控机制容器运行时Docker等工具封装底层技术容器编排系统Kubernetes等管理大规模容器容器技术是现代云计算和微服务架构的基础,它利用Linux内核的命名空间和控制组特性实现轻量级的进程隔离与传统虚拟机相比,容器共享主机内核,启动更快,资源效率更高,非常适合微服务部署Linux提供了多种类型的命名空间隔离PID命名空间进程ID、Network命名空间网络栈、Mount命名空间文件系统挂载点、UTS命名空间主机名、IPC命名空间进程间通信和User命名空间用户ID这些隔离机制使容器中的进程看到独立的系统视图,互不干扰在容器编排系统如Kubernetes中,进程生命周期管理变得更加复杂系统需要处理容器的创建、调度、扩缩容、健康检查和故障恢复理解底层进程管理机制对于设计高可用、高性能的容器化应用至关重要实时进程特性99最高实时优先级Linux实时进程最高优先级值2实时调度策略SCHED_FIFO和SCHED_RR100μs典型延迟目标软实时系统常见响应时间要求0优先级反转风险需要专门防范的实时系统威胁实时进程需要在可预测的时间内响应事件,典型应用包括工业控制、音视频处理、金融交易等对延迟敏感的系统Linux虽然不是严格的实时操作系统,但通过特定的内核配置如PREEMPT_RT补丁和调度策略,可以满足许多软实时应用需求Linux提供两种主要的实时调度策略SCHED_FIFO先进先出和SCHED_RR时间片轮转SCHED_FIFO策略下,高优先级进程会无限期运行直到阻塞或主动让出CPU;SCHED_RR类似但每个进程有时间配额实时进程优先级1-99高于普通进程,确保优先执行实时系统面临的主要挑战包括优先级反转低优先级进程持有高优先级进程需要的资源、不确定性来源中断、内存分页等和资源竞争解决方案包括优先级继承协议、内存锁定、CPU隔离和专用核心等技术,确保关键任务在严格的时间约束内完成课程总结与展望核心知识点回顾我们学习了进程的基本概念与生命周期、进程创建与终止的系统调用、各种进程间通信机制、调度算法与优先级控制、资源限制与监控、进程跟踪与调试技术,以及线程编程与同步机制等核心内容这些知识构成了UNIX/Linux系统编程的基础技术发展趋势进程管理技术持续演进,容器化与微服务架构推动了轻量级隔离技术的发展;多核处理器普及促进了调度器优化和NUMA感知调度;安全需求增长带来了更细粒度的进程权限控制;边缘计算兴起对实时性提出了新要求理解这些趋势有助于把握技术发展方向分布式系统扩展传统进程概念正扩展到分布式环境,出现了跨主机进程管理和调度方案微服务编排平台如Kubernetes实现了集群级别的进程管理,函数即服务FaaS将进程粒度进一步细化,这些都是对传统UNIX进程模型的扩展和演化进阶学习资源推荐深入学习的方向包括Linux内核源码剖析、高级系统编程、容器技术实现原理、实时系统开发、分布式系统设计等建议阅读《UNIX环境高级编程》《Linux内核设计与实现》等经典著作,并通过开源项目实践巩固理论知识。
个人认证
优秀文档
获得点赞 0