一、常见的进程状态与理解 在操作系统内部,有专门用来管理进程的结构体,叫做struct task_struct,也称作进程控制块(PCB),主要包含描述进程的相关信息,如进程用户、进程状态、进程优先级、文件描述符(记录当前进程打开的文件)、主要进程标识的进程号和父进程号: 进程号(PID: Process Identity Number):唯一的标识一个进程,用于区分系统中的各个进程并方便操作系统进行管理; 父进程号:(PPID:Parent Process ID):用于描述一个进程的直接父进程的标识符,每个进程在创建时都会由一个已有的进程(即父进程)生成,这样就形成了进程的层级结构。通过PPID,可以追踪进程的来源,并了解进程之间的关系。 在PCB中记录的进程状态,不过是一些整数,这个整数是多少就代表进程此时处于什么状态。在CPU执行进程时,通过找到进程的PCB,从而找到进程的代码和数据,进而去执行这个进程。下面列举了一些进程状态: 注意:没有+时,默认是后台进程 进程调度(进程状态切换) 进程创建后,进程进入就绪态,当CPU调度到此进程时进入运行态,当时间片用完时,此进程会进入就绪态,如果此进程正在执行一些IO操作(阻塞操作)会进入阻塞态,完成IO操作(阻塞结束)后又可进入就绪态,等待CPU的调度,当进程运行结束即进入结束态。 一、睡眠机制与唤醒机制 睡眠机制: 1)主动睡眠(Blocking Sleep): 进程自愿进入睡眠状态,通常是通过系统调用如sleep()、wait()等。 2)被动睡眠(Interruptible Sleep): 进程在等待某个条件满足(如I/O操作),可以被信号唤醒。 Linux通过内核提供的系统调用来控制进程的睡眠。常用的系统调用有: sleep(): 使进程暂停指定的秒数。 usleep(): 使进程暂停指定的微秒数。 nanosleep(): 使进程暂停指定的纳秒数。 Tips:睡眠机制帮助节省CPU资源,尤其是在I/O密集型任务中;在可中断睡眠状态下,进程在收到信号时会被唤醒并处理信号。 唤醒机制 1)信号(Signal): 进程可以通过接受特定信号被唤醒。 2)条件变量(Condition Variable): 多线程编程中用于同步多个线程的工具,可以让一个线程在某些条件下睡眠并等待被唤醒。 Tips:唤醒机制可以通过信号、I/O事件和线程同步原语(如条件变量)来有效管理进程和线程的状态,更好地利用系统资源,提高程序的响应性与性能。 一、用法实例 1.进程睡眠示例: 使用 sleep() 函数让进程暂停执行一段时间 使用 usleep() 函数,使进程睡眠0.5秒,精确度更高 使用 nanosleep(),使进程睡眠1.5秒,可以精细控制时间 2.进程唤醒实例: 使用信号唤醒进程,进程直到接收到 SIGUSR1 信号被唤醒。 使用 select() 函数等待I/O,如果在5秒内没有输入,select() 会返回,以便进程被唤醒。若有输入,则进程也会被唤醒。 使用条件变量唤醒线程,子线程在条件变量上等待,直到主线程调用 pthread_cond_signal() 唤醒它。主线程在等待2秒后,设置条件并唤醒子线程。(已经描述到这里,线程一并提及一下)
|