1. 请分别简单说一说进程和线程以及它们的区别
- 进程是具有一定功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源调度和分配的一个独立单位。
- 线程是进程的实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
- 一个进程可以有多个线程,多个线程也可以并发执行。more
2. 线程同步的方式有哪些?
- 互斥量:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。
- 信号量:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
- 事件(信号):通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。more
生产者、消费者问题:
Var mutex,empty,full:semaphore:=1,n,0; // 定义三个信号量
buffer:array[0,...,n-1]of item; // 定义缓冲池,容量为n
in,out:integer:=0,0;
begin
parbegin
proceducer:begin // 生产者
repeat
producer an item nextp; // 生产一个产品 .
wait(empty); // 申请一个空缓冲区
wait(mutex); // 申请缓冲池的使用权
buffer(in):=nextp; // 将产品放入缓冲池中
in:=(in+1)mod n; // 下一个空缓冲区地址
signal(mutex); //释放缓冲池使用权
signal(full); // 释放一个满缓冲区
until false;
end
consumer:begin
repeat
wait(full);
wait(mutex);
nextc:=buffer(out);
out:=(out+1)mod n;
signal(mutex);
signal(empty);
consumer the item in nextc;
until false;
end
parend
end
3. 进程的通信方式有哪些?
主要分为:管道、系统IPC(包括消息队列、信号量、共享存储)、SOCKET
管道主要分为:普通管道PIPE 、流管道(s_pipe)、命名管道(name_pipe)
- 管道是一种半双工的通信方式,数据只能单项流动,并且只能在具有亲缘关系的进程间流动,进程的亲缘关系通常是父子进程
- 命名管道也是半双工的通信方式,它允许无亲缘关系的进程间进行通信
- 信号量是一个计数器,用来控制多个进程对资源的访问,它通常作为一种锁机制。
- 消息队列是消息的链表,存放在内核中并由消息队列标识符标识。
- 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
- 共享内存就是映射一段能被其它进程访问的内存,这段共享内存由一个进程创建,但是多个进程可以访问。more
4. 什么是缓冲区溢出?有什么危害?其原因是什么?
缓冲区溢出是指当计算机向缓冲区填充数据时超出了缓冲区本身的容量,溢出的数据覆盖在合法数据上。
危害有以下两点:
- 程序崩溃,导致拒绝额服务
- 跳转并且执行一段恶意代码
造成缓冲区溢出的主要原因是程序中没有仔细检查用户输入。more
5. 什么是死锁?死锁产生的条件?
在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其他进程释放它现在保持着的资源,在未改变这种状态之前都不能向前推进,则称这一组进程产生了死锁。通俗地讲就是两个或者多个进程无限期的阻塞相互等待的一种状态。
死锁产生的四个条件:
- 互斥条件:一个资源一次只能被一个进程使用
- 请求和保持条件:一个进程因请求资源而阻塞时,对已经获得资源保持不放
- 不剥夺条件:进程获得的资源,在未完全使用完之前不能强行剥夺
- 循环等待条件:若干进程之间形成一种头尾相接的环形等待资源关系more
6. 进程有哪几种状态?
- 就绪状态: 进程已经获得除处理机以外的所需要资源,等待分配处理机资源
- 运行状态:占用处理机资源运行,处于此状态的进程数目小于等于CPU数
- 阻塞状态:进程等待某种条件,在条件满足之前无法执行more
7. 分页和分段有什么区别?
- 段是信息的逻辑单位,它是根据用户的需要划分的,因此段对用户是可见的 ;页是信息的物理单位,是为了管理主存的方便而划分的,对用户是透明的。
- 段的大小不固定,有它所完成的功能决定;页大大小固定,由系统决定
- 段向用户提供二维地址空间;页向用户提供的是一维地址空间
- 段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制。more
8. 什么是临界区?如何解决冲突?
每个进程中访问临界资源的那段程序称为临界区,每次只准许一个进程进入临界区,进入后不允许其他进程进入。
- 如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入;
- 任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待;
- 进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区;
- 如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。
9. 什么是中断?中断时CPU做什么工作?
中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序。待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。
10. 程序、进程、线程
内容 | 程序 | 进程 | 线程 |
---|---|---|---|
定义 | 计算机指令的集合,它以文件的形式存储在磁盘上。程序是静态实体(passive Entity),在多道程序系统中,它是不能独立运行的,更不能与其他程序并发执行。 | 不使用【程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此,它不占用系统的运行资源】 | |
使用系统资源情况 | 进程是进程实体(包括:程序段、相关的数据段、进程控制块PCB)的运行过程,是系统进行资源分配和调度的一个独立单位 | 使用【进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源。】 | |
地址空间 | 系统赋予的独立的虚拟地址空间(对于32位进程来说,这个地址空间是4GB) | 在进程的地址空间执行代码。线程只有一个内核对象和一个堆栈,保留的记录很少,因此所需要的内存也很少。因为线程需要的开销比进程少 | |
调度 | 仅是资源分配的基本单位 | 独立调度、分派的基本单位 | |
并发性 | 仅进程间并发(传统OS) | 进程间、线程间并发 | |
拥有资源 | 资源拥有的基本单位 | 基本上不拥有资源 | |
系统开销 | 创建、撤销、切换开销大 | 仅保存少量寄存器内容,开销小。 |
11. 内存池、进程池、线程池。(c++程序员必须掌握)
自定义内存池的思想通过这个”池”字表露无疑,应用程序可以通过系统的内存分配调用预先一次性申请适当大小的内存作为一个内存池,之后应用程序自己对内存的分配和释放则可以通过这个内存池来完成。只有当内存池大小需要动态扩展时,才需要再调用系统的内存分配函数,其他时间对内存的一切操作都在应用程序的掌控之中。
应用程序自定义的内存池根据不同的适用场景又有不同的类型。
从线程安全的角度来分,内存池可以分为单线程内存池和多线程内存池。单线程内存池整个生命周期只被一个线程使用,因而不需要考虑互斥访问的问题;多线程内存池有可能被多个线程共享,因此则需要在每次分配和释放内存时加锁。相对而言,单线程内存池性能更高,而多线程内存池适用范围更广。
从内存池可分配内存单元大小来分,可以分为固定内存池和可变内存池。所谓固定内存池是指应用程序每次从内存池中分配出来的内存单元大小事先已经确定,是固定不变的;而可变内存池则每次分配的内存单元大小可以按需变化,应用范围更广,而性能比固定内存池要低。