进程线程
解决死锁的基本方法?
预防死锁--确保系统永远不会进入死锁状态
避免死锁—在使用前进行判断,只允许不会产生死锁的进程申请资源
检测死锁—允许死锁发生,但是经过检测后将其清除
解除死锁
kmalloc、vmalloc、malloc的区别?
答:
kmalloc和vmalloc是用来分配内核空间的内存;malloc用来分配用户空间的内存vmalloc比kmalloc要慢kmalloc分配的内存在物理地址上是连续的(虚拟地址自然也是连续的);vmalloc只确保分配的内存在虚拟地址空间内是连续的什么是进程?
答:进程是资源分配的最小单位。
进程是指在系统中正在运行的一个应用程序,程序一旦运行就是进程。
进程是系统进行资源分配的独立实体, 且每个进程拥有独立的地址空间。
一个进程可以拥有多个线程,每个线程使用其所属进程的栈空间。
什么是线程?
答:
线程是进程的一个实体,是进程的一条执行路径。
线程是程序执行的最小单位。
好处:1.易于调度
2.提高并发性
3. 开销少。创建线程比创建进程要快,所需开销很少
进程和线程的区别?
多进程、多线程的优缺点⭐⭐⭐⭐
如果是UNIX/linux环境,多线程比多进程成本低,但性能更低。多进程是立体交通系统,虽然造价高,上坡下坡多耗点油,但是不堵车。多线程是平面交通系统,造价低,但红绿灯太多,老堵车什么时候用进程,什么时候用线程⭐⭐⭐
需要频繁创建销毁的优先使用线程;因为对进程来说创建和销毁一个进程代价是很大的。线程的切换速度快,所以在需要大量计算,切换频繁时用线程,还有耗时的操作使用线程可提高应用程序的响应因为对CPU系统的效率使用上线程更占优,所以可能要发展到多机分布的用进程,多核分布用线程;并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求;需要更稳定安全时,适合选择进程;需要速度时,选择线程更好。进程的五个状态?
答:
新建态
就绪态
运行态
阻塞态
终止态
新建状态(New):新创建了一个线程对象。
就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权。即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。
运行状态(Running):就绪状态的线程获取了CPU,执行程序代码
阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
进程间通信的方式有哪些?
答:1.有名管道/无名管道
2.信号
3.消息队列
4.信号量
5.共享内存
6.socket
线程间同步(通讯)的方法?
答:
1.互斥锁提供了以排他方式防止数据结构被并发修改的方法。
2.读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
3.条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用
4.信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
5.信号机制(Signal): 类似进程间的信号处理
如何确定当前线程是繁忙还是阻塞?
答:用ps命令查看
就绪状态的进程在等待什么?
答:
被调度使用cpu的运行权
怎么查看进程使用情况?
答:
top命令
进程调度算法?
先来先到算法:优先运行先到达的进程,类似于队列,先进先出,只需要对进程进行排序即可
短进程优先算法:比较就绪进程的服务时间,取服务时间短的优先
产生死锁的原因是什么?
答:
(1) 因为系统资源不足。
(2) 进程运行推进的顺序不合适。
(3) 资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则
就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
死锁的4个必要条件?
答:
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之
一不满足,就不会发生死锁。
17.什么是线程同步和互斥⭐⭐⭐⭐⭐
同步:
同步,又称直接制约关系,是指多个线程(或进程)为了合作完成任务,必须严格按照规定的 某种先后次序来运行。(盖房子从下到上)
互斥:
互斥,又称间接制约关系,是指系统中的某些共享资源,一次只允许一个线程访问。当一个线程正在访问该临界资源时,其它线程必须等待。(打印机)
18.进程的空间模型⭐⭐⭐⭐
Linux 使用虚拟地址空间,大大增加了进程的寻址空间,由低地址到高地址分别为:
1、只读段:该部分空间只能读,不可写;(包括:代码段、rodata 段(C常量字符串和#define定义的常量) )
2、数据段:保存全局变量、静态变量的空间;
3、堆 :就是平时所说的动态内存, malloc/new 大部分都来源于此。其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。
4、文件映射区域 :如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。
5、栈:用于维护函数调用的上下文空间,一般为 8M ,可通过 ulimit –s 查看。
6、内核虚拟空间:用户代码不可见的内存区域,由内核管理(页表就存放在内核虚拟空间)。
19、孤儿进程、僵尸进程、守护进程的概念
1、孤儿进程 :一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
由于孤儿进程会被init进程给收养,所以孤儿进程不会对系统造成危害
2、僵尸进程: 一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。
僵死进程的危害 :
系统所能使用的进程号有限,如果产生大量的僵尸进程,会导致没有可用的进程号,导致无法产生新的进程。
避免僵尸进程:
让僵尸进程的父进程每隔一段时间来查询子进程是否结束并回收,调用wait()或者waitpid()通知内核释放僵尸僵尸进程
采用信号SIGCHLD通知处理,并在信号处理程序中调用wait()函数
让僵尸进程编程孤儿进程,然后再由init进程回收(也就是手动杀死父进程)
守护进程 : 是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务,一个守护进程的父进程是init进程,因为它真正的父进程在fork出子进程后就先于子进程exit退出了,所以它是一个由init继承的孤儿进程。