pthread_create必须用正确签名void()(void*),参数错会导致运行时崩溃;不join或detach会内存泄漏;mutex漏unlock必死锁;cond_wait必须用while防虚假唤醒。
创建线程必须用 pthread_create,不是 thread_create 或别的名字。它有四个参数:线程ID指针、属性、入口函数、函数参数。最容易出错的是第3个参数——入口函数签名必须是 void* (*)(void*),返回 void* 且只接受一个 void* 参数;如果写成 int func() 或 void func(int),编译可能过(尤其开了 -Wno-format),但运行时栈会被破坏,现象是子线程一执行就 crash 或输出乱码。
NULL,别传 0 或未初始化指针EAGAIN、EINVAL),必须检查返回值,不能只看是否为 NULLpthread_join 是阻塞等待线程结束并回收资源;pthread_detach 是把线程设为“分离态”,结束后系统自动清理。两者互斥:对一个线程既调 join 又调 detach 会导致未定义行为(常见 segfault);对已 join 过的线程再 join,行为未定义(glibc 通常 abort)。
join 也不 detach → 线程退出后变成“僵尸线程”,资源(栈、TCB)不释放,长期运行会内存泄漏pthread_cleanup_push 注册的清理函数可能不执行pthread_detach;想等结果或做善后,必须用 pthread_join
pthread_mutex_t 锁的是临界区逻辑,不是变量本身。它靠程序员显式调用 pthread_mutex_lock/pthread_mutex_unlock 来界定哪段代码不能并发执行。漏掉 unlock 是最常见死锁源头——别的线程在 lock 处永久阻塞,整个程序 hang 住,且 gdb 看堆栈永远停在 futex_wait。
printf 或文件 I/O 包进临界区,否则严重拖慢并发性能PTHREAD_MUTEX_INITIALIZER 或 pthread_mutex_init,全局/静态 mutex 用前者更安全;用完记得 pthread_mutex_destroy(尤其在反复创建销毁线程的场景)pthread_cond_wait 被唤醒后,**不保证条件真的成立**。可能被虚假唤醒(spurious wakeup),也可能多个线程被 signal 唤醒后竞争锁,只有第一个拿到锁的能真正干活,其余仍需重新判断条件。所以必须写成 while (!condition) pthread_cond_wait(...),而不是 if。
cond_signal 后主线程只 if (flag == 1) 就往下走,结果 flag 已被其他线程改回 0,逻
pthread_cond_wait 内部会自动释放 mutex,并在唤醒后重新获取——这个“原子性”是它唯一保证,别指望它帮你校验业务状态多线程里最危险的不是 crash,而是偶尔复现的数据错乱——它不会报错,只会让你在上线后花三天查一个 ++counter 没加锁的 bug。