十一.谈谈你对进程的理解,内核是如何管理进程的?
- 进程是计算机中处于运行中的程序的实体
- 线程是最小的运行单位,而进程是线程的容器
- 程序本身只是指令、数据及其组织形式的描述,进程才是程序(指令和数据)的真正运行实例
1.内核将程序读入内存,为程序分配内存空间 //为程序分配
2.内核为该进程分配进程标识符PID和其他所需资源 //为进程分配
3.内核为进程保存PID及相应的状态信息,把进程放到运行队列中等待执行,程序转化为进程后可以被操作系统的调度程序调度执行了
- 每个进程在系统中都有一个唯一的ID标识它,这个ID就是进程标识符(PID)。因为其唯一性,所以系统可以根据PID准确定位到一个进程
- 进程标识符的类型为pid_t,本质上是一个无符号整形的类型别名
- 程序是可运行的二进制代码文件,把这种文件加载到内存中运行就得到了一个进程(所以你每打开一个程序都会占用一部分系统内存)
- 同一个程序文件可以被加载多次成为不同的进程(你可以打开两个QQ)。进程与进程标识符之间是一对一的关系,而程序与进程之间是一对多的关系
一个进程的可能状态有如下几种:
1) 运行态——已经获得了资源,并且进程正在被 CPU 执行。进程既可运行在内核态,也可运行在用户态。
2) 就绪态——当系统资源已经可用,但由于前一个进程还没有执行完释放 CPU,准备进入运行状态。
3) 可中断睡眠状态——当进程处于可中断等待状态时,系统不会调度该程序执行。当系统产生一个中断或者释放了进程正在等待的资源,或者进程收到一个信号,都可以被唤醒进入就绪状态或者运行态。
4) 不可中断睡眠状态——处于中断等待状态,但是该进程只能被使用 wake_up()函数明确唤醒的时候才可进入就绪状态。
5) 暂停状态——当进程收到 SIGSTOP、SIGSTP、SIGTTIN 或者 SIGTTOU 就会进入暂停状态,收到 SIGCONT 信号即可进入运行态。
6) 僵死态——进程已经停止运行,但是其父进程还没有询问其状态。
十二、 什么是进程死锁?操作进程死锁的原因是什么?
(1)所谓的死锁是指在多道程序系统中,一组进程中的每个进程都无限期地等待被该组进程中的另一个进程所占有且永远不会被释放的资源,这种现象称系统处于死锁状态,简称死锁。处于死锁状态的进程成为死锁进程。
系统发生死锁会大量浪费系统资源甚至会导致整个系统崩溃。
(2)产生死锁的原因主要有两个:
- 一是竞争资源,系统提供的资源有限,不能满足每个进程的需求;
- 二是多道程序运行时,进程的推进顺序不合理。
产生死锁的必要条件
- 互斥条件:进程对所分配到的资源进行排它性使用,在一段时间内某资源只由一个进程占用。
- 请求和保持条件:指一个进程已经保持了至少一个资源,但又提出新的资源请求,而此资源被其他占用,此时请求进程阻塞,但又对自己已经占用的资源保持不放。
- 不剥夺条件:进程已经获得资源,在未使用完之前,不能被剥夺,只能在使用完时,由进程自己释放。
- 环路等待条件:发生死锁时,必然存在一个进程-资源的环形链
注:系统的资源分为两类:
永久性资源(可重生资源),是指那些可供进程重复利用、长期存在的资源,如内存、CPU等硬件资源,以及数据文件、共享程序代码等软件资源。
临时性资源(消耗性资源),是指由某个进程产生、只为另一个进程使用一次、或经过短暂时间后便不可再使用的资源,如 I/O 和时钟中断、消息等。
两种资源都可能导致发生死锁。
处理死锁的方法
l 预防死锁
事先预防,破坏产生死锁的四个必要条件之一。
- 摒弃“请求和保持”条件:
进程在申请资源时,是一次性的。
如何摒弃“请求“:当进程来时,一次性分配所有的资源(如果系统满足),这样就不会再有”请求“了。
如何摒弃“保持“:只要有一个资源得不到分配,也不给这个进程分配其他的资源。
- 摒弃“不剥夺”条件:在这种方法中,进程是逐个提出对资源的要求的。如果一个进程,获得了部分资源,但得不到其它资源,这时,它释放自己所占用的资源。
- 摒弃“环路等待”条件:把资源排序,当进程申请资源时,按序申请。
l 避免死锁
事先预防,并不是破坏产生死锁的四个必要条件,而是用某种方法去防止系统进入不安全状态,目前在较完善的系统中,常用此方法。银行家算法
安全状态:是指系统能按照某种进程顺序(P1,P2,…Pn),来为每一个进程Pi分配其所需要的资源,直到满足每个进程对资源的最大需求,使每个进程都可顺利地完成。如果系统无法找到这样一个安全序列,则称系统处于不安全状态。
l 检测死锁
并不事先采取任何限制性的措施,也不必检查系统是否已经进入不安全区,此方法允许发生死锁,关键是,发生死锁了,系统可以通过检测机构发现死锁,并精确确定与死锁有关的进程和资源,然后,采取适当措施,从系统中将已经发生的死锁清除
l 解除死锁
这是与检测死锁配套使用。当检测到系统已经发生了死锁,要将进程从死锁状态中解脱出来。常用的方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已经处于阻塞状态的进程,使之转为就绪状态,以继续运行。
十三.保持进程同步的方法有哪些?
Linux 下:
Linux 下常见的进程同步方法有:SysVIPC 的 sem(信号量)、file locking / record locking(通过 fcntl 设定的文件锁、记录锁)、futex(基于共享内存的快速用户态互斥锁)。针对线程(pthread)的还有 pthread_mutex 和 pthread_cond(条件变量)。
Linux 下常见的进程通信的方法有 :pipe(管道),FIFO(命名管道),socket(套接字),SysVIPC 的 shm(共享内存)、msg queue(消息队列),mmap(文件映射)。以前还有 STREAM,不过现在比较少见了(好像)。
Windows下:
在Windwos中,进程同步主要有以下几种:互斥量、信号量、事件、可等计时器等几种技术。
在Windows下,进程通信主要有以下几种:内存映射、管道、消息等,但是内存映射是最基础的,因为,其他的进程通信手段在内部都是考内存映射来完成的。
十四.线程同步方式有哪些?优缺点?
现在流行的进程线程同步互斥的控制机制,其实是由最原始,最基本的4中方法实现的:
- 临界区:通过多线程的互串行访问公共资源或一段代码,速度快,适合控制数据访问。
- 互斥量:为协调共同对一个共享资源的单独访问而设计。只有拥有互斥对象的线程才有权限去访问系统的公共资源,因为互斥对象只有一个,所以能够保证资源不会同时被多个线程访问。
- 信号量:为控制一个具有有限数量的用户资源而设计。它允许多个线程在同一时刻去访问同一个资源,但一般需要限制同一时刻访问此资源的最大线程数。
- 事件:用来通知线程有一些事件已发生,从而启动后继任务的开始。