C多线程实现的四种方式_C语言创建线程的四种方法详解

C语言标准本身不支持多线程,pthread_create(POSIX)、C11 、Windows API(CreateThread)及fork均非ISO C标准:前者仅限类Unix系统且需-lpthread;C11线程库现实支持极差,glibc未实现;Windows API完全不可移植;fork创建进程而非线程,不共享内存。

标准 C 语言本身不提供线程支持,pthread_createstd::thread、Windows API 等都不是 C 标准库的一部分。所谓“C 多线程四种方式”,实际是混用了不同平台/标准的实现,必须明确区分适用环境和依赖条件。

pthread_create 是最常见但非标准的方案

POSIX 线程(pthreads)是 Linux/macOS 的事实标准,但需链接 -lpthread,且头文件为 。它不是 ISO C 的一部分,跨 Windows 需 MinGW 或第三方兼容层。

  • 函数原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
  • 线程函数必须返回 void*,参数也必须是 void*,强制类型转换需谨慎
  • 主线程退出时若未调用 pthread_joinpthread_detach,子线程可能被意外终止
  • 错误不通过 errno 报告,而是直接返回错误码(如 EAGAINEINVAL),不能用 perror 打印

C11 理论可用,但现实支持极差

C11 标准引入了 ,提供 thrd_createmtx_lock 等接口,目标是可移植。但截至 2025 年,GCC 和 Clang 默认不启用该功能,MSVC 完全不支持,musl libc 仅部分实现。

  • 启用需编译器显式支持:GCC 要求 -std=c11 -pthread,且仍可能链接失败
  • 即使编译通过,glibc 实际未实现 ,运行时会报 undefined reference to thrd_create
  • 若真要用,建议只在嵌入式场景(如使用 newlib 或 picolibc)中评估,通用开发慎选

Windows API 创建线程(CreateThread)完全不可移植

这是 W

in32 原生方式,头文件为 ,函数为 CreateThread。它与 pthread 语义差异大,比如栈大小控制、线程局部存储(TLS)机制、退出行为(ExitThread vs return)都不同。

  • CreateThread 第四个参数是 LPVOID lpParameter,接收任意指针,无需强转,但回调函数签名是 DWORD WINAPI ThreadProc(LPVOID)
  • 主线程调用 WaitForSingleObject 等待子线程结束,而非 pthread_join
  • 直接调用 CloseHandle 释放线程对象句柄,否则资源泄漏;而 pthread 中 pthread_join 同时完成等待和清理
  • 混用 CreateThread 和 C 运行时(如 malloc/free)有风险,推荐用 _beginthreadex 替代

用 fork + exec 模拟并发?这不是线程

有些资料把 fork 列为“多线程方式”,属于概念混淆。fork 创建的是进程,有独立地址空间、文件描述符副本、不共享全局变量——和线程的共享内存模型本质不同。它开销更大,IPC 需额外机制(pipe、mmap、shm),也不能替代线程同步原语(如 mutex)。

  • fork 后父子进程各自执行,无法用 pthread_mutex_t 保护共享数据(除非用 PTHREAD_PROCESS_SHARED + mmap
  • 信号处理、stdio 缓冲、atexit 注册等行为在 fork 后变得复杂,容易出竞态
  • 若目标是并行计算且无共享状态,fork 可行;但凡涉及共享内存或低延迟协同,就不是正确选择

真正写 C 多线程时,别纠结“四种方法”的分类,先确定目标平台:Linux/macOS 就用 pthread,Windows 就用 CreateThread_beginthreadex,跨平台项目则应封装抽象层或改用 Rust/C++ 等自带标准线程支持的语言。C11 目前只是纸面标准,别在生产环境赌它能跑通。