C多线程_C语言多线程编程基础概念

2026-02-01 00:00:00 作者:星降
标准C语言无内置多线程支持,pthread是POSIX线程库,需链接-lpthread并包含;传参须确保生命周期覆盖线程全程;joinable线程需pthread_join或设为detached;共享变量必须用mutex保护,避免竞态与死锁。

标准 C 语言本身不提供多线程支持,pthread 是 POSIX 标准下的线程库,不是 C 语言内置功能,必须显式链接 -lpthread 且包含

pthread_create 启动线程时传参容易出错

常见错误是直接传栈变量地址,线程还没开始执行,主线程已退出该作用域,导致未定义行为。

  • 传参必须确保生命周期覆盖整个线程运行期:用 malloc 分配的堆内存、全局/静态变量,或主线程同步等待(如 pthread_join)后再释放
  • 不要写 pthread_create(&t, NULL, func, &local_var);改用 int *p = malloc(sizeof(int)); *p = local_var; pthread_create(..., p);
  • 线程函数参数类型必须是 void *,接收后需强制转回原类型,例如 int val = *(int *)arg;

线程退出后资源不自动清理

pthread_create 创建的线程默认是“可连接的(joinable)”,退出后内核保留其退出状态,直到另一线程调用 pthread_join。否则会泄漏资源,类似进程中的僵尸进程。

  • 若不需要获取返回值,创建前设为分离态:pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&t, &attr, ...);
  • 或创建后立即分离:pthread_detach(t);,但要确保 t 有效且未被 join
  • 调用 pthread_join(t, &retval) 会阻塞,直到 t 终止;retval 可为 NULL

多个线程读写同一变量必须加锁

C 语言没有原子操作保证(C11 是例外),普通 int counter++ 在多线程下不是原子的——它包含读、加、写三步,可能被中断并交错执

行,结果不可预测。

  • pthread_mutex_t 保护临界区:声明为全局或静态,用 pthread_mutex_init 初始化(或 PTHREAD_MUTEX_INITIALIZER
  • 每次访问共享变量前调用 pthread_mutex_lock,结束后立即 pthread_mutex_unlock
  • 避免死锁:锁的获取顺序必须一致;不要在持有锁时调用可能阻塞或再次申请锁的函数(如 printf 不推荐在锁内调用)
  • 注意:static int counter; 仍是共享的,即使声明在函数内

最常被忽略的是:忘记初始化互斥量、忘记销毁(pthread_mutex_destroy)、在 fork 后子进程中继续使用父进程创建的线程或锁——这些都会引发难以复现的崩溃或数据错乱。

猜你喜欢

联络方式:

400 9058 355

邮箱:8955556@qq.com

Q Q:8955556

微信二维码
在线咨询 拨打电话

电话

400 9058 355

微信二维码

微信二维码