C多线程面试题_常见C语言多线程面试题汇总

pthread_create必须用正确签名void()(void*),参数错会导致运行时崩溃;不join或detach会内存泄漏;mutex漏unlock必死锁;cond_wait必须用while防虚假唤醒。

c多线程面试题_常见c语言多线程面试题汇总

pthread_create 怎么用?参数传错会怎样?

创建线程必须用 pthread_create,不是 thread_create 或别的名字。它有四个参数:线程ID指针、属性、入口函数、函数参数。最容易出错的是第3个参数——入口函数签名必须是 void* (*)(void*),返回 void* 且只接受一个 void* 参数;如果写成 int func()void func(int),编译可能过(尤其开了 -Wno-format),但运行时会被破坏,现象是子线程一执行就 crash 或输出乱码。

  • 线程函数不能是局部变量地址(比如直接传 &i),因为主线程 return 后栈帧销毁,子线程访问就是野指针
  • 若不需要传参,第4个参数传 NULL,别传 0 或未初始化指针
  • 成功返回 0,失败不返回 -1,而是返回错误码(如 EAGAINEINVAL),必须检查返回值,不能只看是否为 NULL

pthread_join 和 pthread_detach 的区别与误用场景

pthread_join 是阻塞等待线程结束并回收资源;pthread_detach 是把线程设为“分离态”,结束后系统自动清理。两者互斥:对一个线程既调 join 又调 detach 会导致未定义行为(常见 segfault);对已 join 过的线程再 join,行为未定义(glibc 通常 abort)。

  • 不调 join 也不 detach → 线程退出后变成“僵尸线程”,资源(栈、TCB)不释放,长期运行会内存泄漏
  • 主线程 exit() 前没处理子线程 → 整个进程终止,子线程强制结束,pthread_cleanup_push 注册的清理函数可能不执行
  • 想让线程后台运行且不关心结果,用 pthread_detach;想等结果或做善后,必须用 pthread_join

mutex 锁住什么?为什么只加锁不 unlock 会卡死?

pthread_mutex_t 锁的是临界区逻辑,不是变量本身。它靠程序员显式调用 pthread_mutex_lock/pthread_mutex_unlock 来界定哪段代码不能并发执行。漏掉 unlock 是最常见死锁源头——别的线程在 lock 处永久阻塞,整个程序 hang 住,且 gdb 看堆栈永远停在 futex_wait

  • 锁粒度要小:不要把 printf 或文件 I/O 包进临界区,否则严重拖慢并发性能
  • 避免嵌套锁:A 锁了 mutex1 再去 lock mutex2,B 反过来,就容易循环等待
  • 初始化必须用 PTHREAD_MUTEX_INITIALIZERpthread_mutex_init,全局/静态 mutex 用前者更安全;用完记得 pthread_mutex_destroy(尤其在反复创建销毁线程的场景)

条件变量 wait 为什么必须配合 while 而不是 if?

pthread_cond_wait 被唤醒后,**不保证条件真的成立**。可能被虚假唤醒(spurious wakeup),也可能多个线程被 signal 唤醒后竞争锁,只有第一个拿到锁的能真正干活,其余仍需重新判断条件。所以必须写成 while (!condition) pthread_cond_wait(...),而不是 if

灵光

灵光

蚂蚁集团推出的全模态AI助手

下载

立即学习C语言免费学习笔记(深入)”;

  • 典型错误:子线程 cond_signal 后主线程只 if (flag == 1) 就往下走,结果 flag 已被其他线程改回 0,逻辑错乱
  • pthread_cond_wait 内部会自动释放 mutex,并在唤醒后重新获取——这个“原子性”是它唯一保证,别指望它帮你校验业务状态
  • 务必确保 signal 和 wait 在同一 mutex 保护下操作共享条件变量,否则存在竞态:signal 发生在 wait 进入阻塞前,就会丢失信号

多线程里最危险的不是 crash,而是偶尔复现的数据错乱——它不会报错,只会让你在上线后花三天查一个 ++counter 没加锁的 bug。

https://www.php.cn/faq/2018343.html

发表回复

Your email address will not be published. Required fields are marked *