POSIX 线程与同步原语与 POSIX 信号与进程控制

共 62 题
#

1. POSIX.1-2017 定义的 pthread_create/pthread_join/pthread_exit 与 Linux 内核 task_struct 的对应

A pthread 是独立进程
B 每个 pthread 对应一个内核 task_struct,由 clone 创建,共享地址空间 ✓ 正确答案
C pthread_join 不会回收资源
D pthread 与内核无对应
#

2. pthread_key_t 的线程局部存储(TLS)API,pthread_setspecific 与 pthread_getspecific 的用法

A 每线程通过 pthread_key 维护独立线程局部值,键可注册析构函数清理 ✓ 正确答案
B 所有线程共享同一值
C setspecific 会影响其他线程
D TLS 无需清理
#

3. pthread_kill 的线程级信号投递与异步信号安全

A pthread_kill 投递到所有线程
B pthread_kill 向指定线程投递信号,处理器只能调用异步信号安全函数 ✓ 正确答案
C 信号处理器可随意调用 malloc
D 异步信号安全函数很丰富
#

4. pthread_setaffinity_np 的 CPU 亲和性绑定

A 绑定会降低缓存命中
B 绑定后线程可自由迁移
C 绑定与 NUMA 无关
D pthread_setaffinity_np 把线程绑定到指定 CPU,减少缓存抖动并提升确定性 ✓ 正确答案
#

5. pthread_setschedparam 的实时线程调度策略(SCHED_FIFO/SCHED_RR)

A 实时线程不会饿死其他线程
B 两者完全相同
C 实时策略优先级低于普通线程
D SCHED_FIFO 同优先级 FIFO 不时间片轮转,SCHED_RR 同优先级按时间片轮转 ✓ 正确答案
#

6. pthread 的 robust mutex(ROBUST)与进程间共享锁恢复

A 崩溃后锁永久卡死
B 普通 mutex 也能自动恢复
C robust mutex 只用于线程内
D 持有者崩溃后内核让新获取者收到 EOWNERDEAD,可用 consistent 恢复锁 ✓ 正确答案
#

7. pthread_atfork 的 fork handler 与多线程 fork 的死锁风险

A 子进程的锁必然正常
B fork 复制所有线程
C fork 后子进程只复制调用线程,需用 pthread_atfork 钩子统一锁状态防死锁 ✓ 正确答案
D pthread_atfork 与锁无关
#

8. fork() 的写时复制(COW)与内存共享边界

A fork 立即复制全部内存
B fork 后父子共享物理页(只读),写入时才复制,避免全量复制 ✓ 正确答案
C 父子内存永不共享
D COW 与写无关
#

9. fork+exec 的进程创建模式 vs posix_spawn 的单次系统调用

A posix_spawn 单次调用创建进程,避免多线程 fork 死锁与 COW 浪费 ✓ 正确答案
B posix_spawn 是两次系统调用
C fork+exec 更安全
D 两者完全相同
#

10. waitpid 与 WNOHANG、WUNTRACED 标志的非阻塞子进程管理

A WNOHANG 使 waitpid 非阻塞返回,WUNTRACED 报告停止的子进程 ✓ 正确答案
B WNOHANG 让 waitpid 永远阻塞
C WUNTRACED 报告退出
D waitpid 只能阻塞等待
#

11. 异步信号安全函数列表为何有限,malloc 因持有 arena 锁、printf 因持有 stdio 缓冲锁而为何不能在信号处理器中安全调用?

A 加锁与信号无关
B malloc 是异步信号安全的
C 信号处理器可自由调用 printf
D malloc 持 arena 锁、printf 持 stdio 锁,信号处理器中调用会死锁 ✓ 正确答案
#

12. POSIX 信号在多线程程序中的"信号掩码继承"与线程投递

A 所有信号只投递给主线程
B 掩码是进程级共享
C 新线程继承创建者掩码,进程级信号由任一未阻塞线程处理,pthread_kill 定向投递 ✓ 正确答案
D pthread_kill 投递给所有线程
#

13. fork() 后的线程行为,仅调用线程存在、子线程消失

A fork 后子进程只保留调用线程,其他线程消失,可能遗留锁导致死锁 ✓ 正确答案
B fork 复制所有线程
C 子进程线程状态完整
D 其他线程的锁无影响
#

14. signalfd 将信号转为文件描述符的"信号即 I/O"模式

A signalfd 把信号转为 fd 可读事件,配合 epoll 在事件循环中同步处理信号 ✓ 正确答案
B signalfd 仍需异步信号处理器
C signalfd 无需阻塞信号
D signalfd 与 epoll 无关
#

15. vfork() 的挂起父进程与子进程共享地址空间

A vfork 复制全部内存
B vfork 挂起父进程,子进程共享地址空间,应在 exec 或 _exit 前使用 ✓ 正确答案
C vfork 父子同时运行
D vfork 子进程可任意修改父进程内存
#

16. pthread_cancel 的异步 vs 延迟取消(deferred cancellation)与 cancellation point

A 延迟取消在任意指令响应
B 异步取消更安全
C 延迟取消在 cancellation point 响应并执行清理,异步取消随时打断较危险 ✓ 正确答案
D 取消无需清理
#

17. pthread_mutex 的 priority inversion 与 PTHREAD_PRIO_INHERIT 协议

A 高优先级线程总是先运行
B 优先级反转无需处理
C PRIO_INHERIT 与优先级无关
D 优先级继承把持锁者临时提升到等待者优先级,缓解优先级反转 ✓ 正确答案
#

18. pthread_mutex 底层如何用 futex 实现,慢路径如何进入内核睡眠,为什么说无竞争时加解锁不产生系统调用?

A futex 无快速路径
B 加锁总是进内核
C 无竞争时加解锁只做用户态原子操作,竞争时才进内核睡眠唤醒 ✓ 正确答案
D 竞争时也无需进内核
#

19. POSIX 信号的分类,标准信号(SIGTERM/SIGINT)与实时信号(SIGRTMIN+)的差异

A 实时信号排队、可携带数据且有优先级,标准信号不排队 ✓ 正确答案
B 标准信号也排队
C 实时信号不能携带数据
D 两者相同
#

20. sigaction 的 SA_RESTART、SA_NOCLDWAIT、SA_NODEFER 标志的工程语义

A SA_NODEFER 阻塞信号
B SA_RESTART 让 I/O 返回 EINTR
C SA_NOCLDWAIT 会产生僵尸进程
D SA_RESTART 自动重启被打断的 I/O,SA_NOCLDWAIT 自动回收子进程 ✓ 正确答案
#

21. sigwait 与同步信号接收的"信号即事件"模式

A sigwait 是异步处理器
B sigwait 同步接收信号并处理,规避异步信号安全限制 ✓ 正确答案
C sigwait 无法加锁
D sigwait 需用信号处理器
#

22. signalfd + epoll 的事件循环中信号统一处理

A epoll 无法处理信号 fd
B 信号需异步处理器
C 信号经 signalfd 转 fd 加入 epoll,与 I/O 事件统一同步处理 ✓ 正确答案
D 信号与其他事件分离
#

23. POSIX timer 的 SIGEV_SIGNAL、SIGEV_THREAD、SIGEV_THREAD_ID 通知模式

A 三者相同
B SIGEV_SIGNAL 发信号,SIGEV_THREAD 创建线程回调,SIGEV_THREAD_ID 投递到指定线程 ✓ 正确答案
C SIGEV_THREAD 不创建线程
D SIGEV_THREAD_ID 每次建线程
#

24. POSIX 实时信号的排队(queued)行为与标准信号的合并

A 实时信号合并
B 标准信号也排队
C 实时信号排队且不丢,标准信号合并(可能丢) ✓ 正确答案
D 两者都不丢
#

25. pthread_attr_t 的分离状态(joinable/detached)与栈大小(stacksize)的工程取舍

A 栈大小与线程数无关
B joinable 自动回收
C detached 可以 join
D detached 线程退出自动回收,joinable 需 join,大量线程常用小栈+detached ✓ 正确答案
#

26. pthread_cond_wait 的 spurious wakeup 与 while 循环守卫

A wait 返回后条件必然满足
B 用 if 判断即可
C spurious wakeup 不会发生
D 应用 while 循环守卫重新检查谓词,避免 spurious wakeup 误判 ✓ 正确答案
#

27. pthread_mutex_t 的 normal、recursive、error-checking、default 四类型差异

A recursive 只能加锁一次
B 所有类型都可重复加锁
C error-check 重复加锁会死锁
D recursive 可重复加锁并计数、error-check 对非法操作返回错误、normal 重复加锁死锁 ✓ 正确答案
#

28. pthread_once_t 的单次初始化(pthread_once)替代 static initializer

A 并发下会重复初始化
B 每次调用都执行初始化
C 需手工加锁保证
D pthread_once 保证初始化例程多线程下只执行一次 ✓ 正确答案
#

29. pthread_rwlock_t 的 reader/writer 偏好策略与写线程饥饿风险

A 读者优先可能写饥饿,Linux 默认写者优先避免写饥饿 ✓ 正确答案
B 写者优先会写饥饿
C 读写锁只允许一个读者
D 偏好策略无影响
#

30. pthread_spinlock_t 的忙等待(busy-wait)与适用场景

A 自旋锁会睡眠
B 自旋锁适合长临界区
C 自旋锁忙等不睡眠,适合短临界区,长临界区/高竞争会浪费 CPU ✓ 正确答案
D 自旋锁不占用 CPU
#

31. pthread_cleanup_push/pthread_cleanup_pop 的资源清理栈

A 清理函数不释放锁
B 清理函数只在正常退出时执行
C push/pop 无需成对
D 线程取消/退出时按 LIFO 执行注册的清理函数,保证资源释放 ✓ 正确答案
#

32. pthread 的 errno 与线程局部 errno 边界

A errno 是线程局部变量,各线程独立,避免错误码互相覆盖 ✓ 正确答案
B errno 是全局共享的
C 线程会覆盖其他线程的 errno
D errno 与线程无关
#

33. SIGCHLD 的处理与僵尸进程(zombie process)清理

A 无需处理 SIGCHLD
B 子进程退出自动回收
C 僵尸进程不占资源
D 父进程收到 SIGCHLD 后 waitpid 回收子进程,否则产生僵尸进程 ✓ 正确答案
#

34. exec() 家族(execl/execv/execlp/execvp/execle/execve)的语义差异

A execve 是唯一变体
B exec 成功后 PID 改变
C 所有变体相同
D l 用参数列表、v 用参数数组、p 在 PATH 查找、e 指定环境 ✓ 正确答案
#

35. SIGRTMIN 到 SIGRTMAX 的实时信号优先级与排队(queued)行为?

A 数字大的优先级高
B 数字小的实时信号优先级高,且可排队可靠投递 ✓ 正确答案
C 实时信号不排队
D 每个信号只能投递一次
#

36. posix_spawnp 在 PATH 解析与 file action(posix_spawn_file_actions_t)的工程价值?

A posix_spawnp 在 PATH 查找,file action 在 exec 前配置 fd,避免竞态 ✓ 正确答案
B posix_spawnp 不查 PATH
C file action 与 fd 无关
D 需手动 fork 后操作 fd
#

37. posix_spawn 在 POSIX 1003.1a 异步执行 fork+exec 的工程价值?

A posix_spawn 单次调用完成创建+执行,避免多线程 fork 死锁与 COW 浪费 ✓ 正确答案
B posix_spawn 需要先 fork
C posix_spawn 与 fork+exec 等价
D posix_spawn 适合多线程 fork
#

38. posix_spawn 在 multithread program 避免 fork deadlock 的工程价值?

A 多线程 fork 无死锁风险
B posix_spawn 也会死锁
C posix_spawn 不复制父进程可能被消失线程持有的锁,规避 fork 死锁 ✓ 正确答案
D posix_spawn 与锁无关
#

39. getrandom 在 early boot 阻塞(flags=0)的工程边界?

A flags=0 在熵池未就绪时阻塞,启动早期可用 GRND_NONBLOCK 避免挂起 ✓ 正确答案
B getrandom 从不阻塞
C /dev/urandom 也阻塞
D 熵池总是立即就绪
#

40. getrandom(2) 系统调用在 Linux 3.17+ 阻塞 vs 非阻塞模式的工程价值?

A 阻塞模式性能最好
B /dev/urandom 也可靠且不阻塞
C GRND_NONBLOCK 保证熵充足
D 阻塞模式保证熵充足(安全关键),GRND_NONBLOCK 避免阻塞(非关键) ✓ 正确答案
#

41. 条件变量的丢失唤醒(lost wakeup),为什么必须先加锁再检查谓词,predicate 判断与 wait 之间如何防止竞态?

A signal 无需持锁
B 可在无锁情况下检查谓词
C lost wakeup 无法避免
D 必须先持锁检查谓词再 wait,wait 原子释放锁,避免谓词满足但错过唤醒 ✓ 正确答案
#

42. seqlock(顺序锁)与读写锁的差异,为什么 seqlock 写者优先且读者可能重试,适合哪些读写比场景?

A seqlock 适合复杂数据结构
B seqlock 写者等待读者
C 读者永不重试
D seqlock 写者优先、读者校验序列号重试,适合读多写少的简单数据 ✓ 正确答案
#

43. fork、vfork、posix_spawn 在地址空间复制、父进程阻塞和多线程安全性上分别有什么语义?

A posix_spawn 有 fork 死锁风险
B fork 父进程阻塞
C vfork 父子并发
D fork 复制地址空间父子并发,vfork 父阻塞共享地址,posix_spawn 多线程安全 ✓ 正确答案
#

44. execve 成功后哪些进程属性会保留,哪些信号处置、映射和线程状态会被重置?

A 信号处理器保留
B execve 改变 PID
C execve 保留 PID/fd/掩码,重置自定义信号处理器、内存映射与线程状态 ✓ 正确答案
D 线程状态保留
#

45. 进程 PID、PGID、SID、TID 在会话、进程组与线程三者之间的归属与控制差异是什么?

A 会话含进程组、进程组含进程、进程含线程,TID 标识线程,PGID 标识进程组 ✓ 正确答案
B TID 与 PID 相同
C 进程组属于线程
D setsid 建立控制终端
#

46. fork 之后父进程先于子进程退出再被 init 接管时,子进程是否会变成孤儿并被回收?

A 孤儿进程永远无人回收
B 父进程先退出,子进程被 init 或 subreaper 接管并最终回收 ✓ 正确答案
C 孤儿进程自动退出
D init 不回收孤儿进程
#

47. 写时复制(COW)页在 fork 后由谁触发复制,触发后哪些资源会同步增长?

A COW 复制不耗内存
B 读操作触发复制
C 复制后物理页仍共享
D 任一进程写入共享页时触发复制,写者获得独立物理页,RSS 随写入增长 ✓ 正确答案
#

48. 设计守护进程优雅退出流程时,如何协调 SIGTERM、在途请求、子进程回收与退出码?

A 退出码总是 0
B SIGTERM 立即退出
C 无需等待在途请求
D SIGTERM 只设标志,主流程停止接新、等待在途请求、回收子进程后以合理码退出 ✓ 正确答案
#

49. 容器内进程 1 接管僵尸进程后是否仍可观测到退出码与资源占用,差别来自 procfs 还是 cgroup?

A PID 1 无需 reap 子进程
B 资源占用在 procfs
C 进程与退出码在 procfs 观测,资源占用在 cgroup 聚合,PID 1 应 reap 子进程 ✓ 正确答案
D 僵尸进程不占进程表
#

50. 多线程进程中 fork 仅复制调用线程,调用 pthread_atfork 注册的 prepare/parent/child 钩子各自承担什么责任?

A parent 只负责拿锁
B prepare 在 fork 后执行
C prepare 在 fork 前统一拿锁,parent/child 在 fork 后各自释放,保证锁状态一致 ✓ 正确答案
D child 释放父进程的锁
#

51. posix_spawn 与 fork+exec 相比在文件描述符继承、信号掩码重置和 attribute flag 上做了哪些工程取舍?

A fork+exec 更安全
B posix_spawn 无法配置 fd
C posix_spawn 用 file action 配置 fd、用 attribute flag 配置信号,更显式原子 ✓ 正确答案
D 两者 fd 继承相同
#

52. 信号掩码(sigprocmask、pthread_sigmask)与信号阻塞的工程应用

A 阻塞的信号挂起,配合 sigwait/signalfd 同步处理,多线程用 pthread_sigmask ✓ 正确答案
B sigprocmask 用于多线程
C 阻塞的信号丢弃
D 掩码与信号处理无关
#

53. sigprocmask 阻塞期间产生的信号如何进入 pending 集合,sigpending 查询与解除阻塞后的投递如何交互?

A sigpending 移除阻塞
B 阻塞的信号丢弃
C 阻塞期间信号进 pending,sigpending 查询,解除阻塞后投递 ✓ 正确答案
D 解除阻塞不投递
#

54. kill、raise、pthread_kill 的进程内/进程间投递差异

A pthread_kill 投递到进程组
B kill 投递到线程
C raise 投递到其他进程
D kill 投递到进程,raise 投递本进程,pthread_kill 投递指定线程 ✓ 正确答案
#

55. setrlimit 的 RLIMIT_NOFILE、RLIMIT_NPROC、RLIMIT_AS 的资源限制

A RLIMIT_AS 限制 fd 数
B RLIMIT_NOFILE 限制线程数
C RLIMIT_NOFILE 限制 fd 数,RLIMIT_NPROC 限制进程/线程数,RLIMIT_AS 限制地址空间 ✓ 正确答案
D NPROC 限制内存
#

56. SA_SIGINFO 处理器通过 siginfo_t 能取得 si_addr、si_pid 等哪些额外信息,常用于区分故障来源?

A si_code 是信号值
B SA_SIGINFO 只提供信号编号
C si_addr 是发送者
D siginfo_t 提供 si_addr 故障地址、si_code 来源、si_pid 发送者,用于诊断故障 ✓ 正确答案
#

57. sigqueue(2) 在附带 union sigval(int 或 ptr)的工程价值?

A sigqueue 只能发标准信号
B sigqueue 发送带 union sigval 数据的实时信号,可排队,接收方经 siginfo_t.si_value 读取 ✓ 正确答案
C sigqueue 不携带数据
D sigqueue 与 kill 完全相同
#

58. C++11 std::thread 无 cancellation token 的工程差异?

A std::thread 有 pthread_cancel
B std::thread 可异步终止线程
C std::thread 无内置取消,需用原子标志/stop_token 协作式取消 ✓ 正确答案
D 线程无需检查取消标志
#

59. getentropy(3) 在 Linux/BSD/macOS 兼容性封装的工程价值?

A getentropy 非加密安全
B getentropy 仅 Linux 可用
C getentropy 提供跨平台统一的安全随机数接口,封装内核随机源 ✓ 正确答案
D 需直接读 /dev/urandom
#

60. volatile sig_atomic_t 在信号处理器中的角色,为什么普通全局变量的读写可能不是原子的,如何正确共享标志?

A 普通 long 读是原子的
B 用 volatile sig_atomic_t 保证原子读写,普通变量可能非原子且被优化 ✓ 正确答案
C volatile 会破坏信号安全
D 处理器可自由写复杂状态
#

61. Unix 会话(session)、进程组与控制终端的关系,setsid 为何能创建新会话并脱离控制终端,守护进程还需哪些步骤彻底脱离终端,终端关闭时 SIGHUP 的发送对象是谁?

A 守护进程无需 chdir
B setsid 保留控制终端
C 终端关闭发送 SIGHUP 给后台进程
D setsid 创建新会话并脱离控制终端,守护进程还需 fork/chdir/重定向 fd 彻底脱离 ✓ 正确答案
#

62. 僵尸进程与孤儿进程如何产生,subreaper 与 PID 1 分别承担什么回收职责?

A 僵尸自动被回收
B 僵尸是父未 wait 回收,孤儿被 PID 1 或 subreaper 接管,subreaper 局部回收子树 ✓ 正确答案
C 孤儿无人接管
D subreaper 是全局回收者