✍个人博客:https://blog.csdn.net/Newin2020?type=blog
📣专栏地址:https://blog.csdn.net/newin2020/category_12820365.html
📚专栏简介:在这个专栏中,我将会分享操作系统面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
85. 如何避免僵尸进程?
- 通过 signal(SIGCHLD, SIG_IGN) 通知内核对子进程的结束不关心,由内核回收。如果不想让父进程挂起,可以在父进程中加入一条语句:signal(SIGCHLD,SIG_IGN); 表示父进程忽略 SIGCHLD 信号,该信号是子进程退出的时候向父进程发送的。
- 父进程调用 wait/waitpid 等函数等待子进程结束,如果尚无子进程退出 wait 会导致父进程阻塞。waitpid 可以通过传递 WNOHANG 使父进程不阻塞立即返回。
- 如果父进程很忙可以用 signal 注册信号处理函数,在信号处理函数调用 wait/waitpid 等待子进程退出。
- 通过两次调用 fork。父进程首先调用 fork 创建一个子进程然后 waitpid 等待子进程退出,子进程再 fork 一个孙进程后退出。这样子进程退出后会被父进程等待回收,而对于孙子进程其父进程已经退出所以孙进程成为一个孤儿进程,孤儿进程由 init 进程接管,孙进程结束后,init 会等待回收。
第一种方法忽略 SIGCHLD 信号,这常用于并发服务器的性能的一个技巧。因为并发服务器常常 fork 很多子进程,子进程终结之后需要服务器进程去 wait 清理资源。如果将此信号的处理方式设为忽略,可让内核把僵尸子进程转交给 init 进程去处理,省去了大量僵尸进程占用系统资源。
86. 用户线程是什么?
-
用户线程(User Thread):在用户空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理;
用户线程的创建、销毁、切换以及线程调度等操作都是由用户空间的线程库完成的,操作系统对于用户线程是不可知的。用户线程的优点是创建和销毁开销较小,并且线程切换的开销相对较小,适用于需要频繁创建和销毁线程的场景。但是,用户线程的缺点是无法充分利用多核处理器,并且一个用户线程的阻塞或死锁可能会阻塞整个进程。
87. 内核线程是什么?
-
内核线程(Kernel Thread):在内核中实现的线程,是由内核管理的线程;
内核线程的创建和销毁、线程的切换、线程调度等操作都由操作系统内核负责。内核线程的优点是能够充分利用多核处理器的并行能力,并且一个内核线程的阻塞不会影响其他内核线程的执行。但是,内核线程的创建和销毁开销相对较大,并且线程切换的开销也相对较大。