C/C++ 面试复习笔记(6)

发布于:2025-06-13 ⋅ 阅读:(21) ⋅ 点赞:(0)

1.文件锁(如flock()或fcntl()锁)是绑定到文件表项还是V节点?

flock()锁:绑定到文件表项(struct file),进程复制文件描述符(如fork()或dup())时锁会被 继承,导致同一进程的多个描述符共享锁。

fcntl()记录锁:绑定到Vnode 和进程,通过struct inode管理锁的持有者,不同进程的锁会冲突。

2.如何检测和解决文件锁导致的死锁(Deadlock)?

死锁场景:

进程A锁定区域1后请求区域2,进程B锁定区域2后请求区域1,互相等待。

检测方法:

超时机制:设置锁请求超时(如fcntl结合信号处理)。

工具分析:使用lslocks命令查看系统锁状态,定位互相等待的进程。

解决方案:

锁顺序一致性:所有进程按相同顺序请求锁。

锁范围最小化:减少单次锁定的区域,缩短持有时间。

死锁恢复:强制终止某个进程释放锁(最后手段)。

3.既然已经有了进程,为何还要有线程?

创建和销毁进程的系统开销通常较大,基于线程的并发具有更低的成本

进程间的数据交换需要借助专门的通信机制,而线程之间天然共享数据

丰富的线程同步机制,使在宏观异步的背景下实现微观的同步代价极低

4.进程的调度算法都有哪些?

时间片轮转调度算法:将处理机交给位于就绪队列队首的进程,为其分配一个时间片,时间 片到期后将该进程排到就绪队列末尾,再从队首调度下一个进程

长等候时间优先调度算法:将处理机交给就绪队列中等候时间最长的进程,待其终止或主动 放弃处理机后再调度下一个进程

短运行时间优先调度算法:将处理机交给就绪队列中预计运行时间最短的进程,待其终止或 主动放弃处理机后再调度下一个进程

短剩余时间优先调度算法:将处理机交给就绪队列中预计运行时间最短的进程,待其终止或 主动放弃处理机后再调度下一个进程,但如果就绪队列中有预计剩余时间更短的进程,则抢占当前进程的处理机,优先执行

高响应比优先调度算法:将处理机交给就绪队列中响应比(等候时间与预计运行时间之比) 最高的进程,待其终止或主动放弃处理机后再调度下一个进程

优先级调度算法:将处理机交给就绪队列中优先级最高的进程,待其终止或主动放弃处理机 后再调度下一个进程

5.kill -9 和 kill -15 的区别是什么?何时应使用哪种信号?

kill -9(SIGKILL):

强制终止进程,不可被捕获或忽略,可能导致资源未释放。

使用场景:进程无响应,需立即终止。

kill -15(SIGTERM):

优雅终止进程,进程可捕获信号并执行清理操作(如保存数据)。

使用场景:正常终止进程,允许其自我清理。

6.进程的终止方式有哪些?

正常终止:

1、从main函数返回

2、调用exit函数结束

3、调用exit 或Exit 函数结束

异常终止:

1、当进程执行了某些在系统看来具有危险性的操作,或系统本身发生了某种故障或意外

2、人为触发信号,例如Ctrl + c

3、向进程自己发送信号,例如调用abort函数

7.如何避免僵尸进程?

方法一:显式忽略(SIG_IGN)子进程终止信号(SIGCHLD),由系统内核自动回收子进程

方法二:在父进程中调用wait或waitpid函数,等待子进程终止并回收之

方法三:在父进程中捕获子进程终止信号(SIGCHLD),在信号处理函数中通过wait或waitpid回收子进程

方法四:先fork 一个儿子进程,再在儿子进程中fork 一个孙子进程,儿子进程随即终止并被其父进程回收,孙子进程成为孤儿进程,由init进程负责回收

8.如果一个父进程持续产生僵尸进程,可能是什么原因?

可能原因: 父进程未正确调用wait()或忽略SIGCHLD信号。 父进程存在逻辑错误(如仅处理第一个子进程,后续子进程未回收)。 父进程陷入死循环,无法执行到wait()代码。