0

0

C多线程并发处理方式_C语言线程并发处理策略

煙雲

煙雲

发布时间:2026-01-25 11:41:03

|

602人浏览过

|

来源于php中文网

原创

pthread_create需显式设置栈大小以防溢出,共享变量必须加锁避免竞态,线程退出后须pthread_join或pthread_detach清理资源,信号与多线程交互应避免pthread_kill而改用条件变量或事件通信。

c多线程并发处理方式_c语言线程并发处理策略

pthread_create 启动线程时必须传入有效空间

很多初学者直接传 NULLpthread_create 的第四个参数(线程属性),以为系统会自动分配,结果在线程函数里一用局部变量就崩溃。这不是随机错误,而是因为默认栈大小通常只有 2MB(Linux 下),且无法动态扩展;若线程递归过深或分配大数组(比如 char buf[1024*1024]),就会触发栈溢出,segfault 或静默破坏相邻内存。

实操建议:

  • 避免在多线程中定义超大栈变量;改用 malloc 分配堆内存,并确保线程退出前 free
  • 如需更大栈,用 pthread_attr_setstacksize 显式设置,例如:
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, 8 * 1024 * 1024); // 8MB
    pthread_create(&tid, &attr, thread_func, arg);
    pthread_attr_destroy(&attr);
  • 注意:栈大小不能小于 PTHREAD_STACK_MIN(通常是 16KB),也不能超过系统限制(ulimit -s

共享变量不加锁导致的竞态不是“偶尔出错”,而是必然不可预测

int counter = 0; 被两个线程同时执行 counter++,最终结果大概率是 1 而不是 2——这不是概率问题,是 counter++ 在汇编层面至少包含三步:读取、加 1、写回。两个线程可能交错执行这三步,造成一次更新被覆盖。

常见误判:

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

  • “我只读不写,不用锁” → 错。即使只读,若另一线程正在写,你可能读到中间状态(非原子写入,尤其结构体或 64 位变量在 32 位平台)
  • “我用 volatile 就安全了” → 错。volatile 只禁用编译器优化,不阻止 CPU 重排序,也不提供原子性或内存屏障
  • “我 sleep 一下就能错开” → 错。这是典型的“靠运气编程”,在高负载或不同 CPU 架构下立即失效

正确做法:对共享变量的读写,统一用 pthread_mutex_t 保护;若只是计数,可考虑 __atomic_add_fetch(GCC 内置原子操作),但要注意平台兼容性。

OpenMP多线程编程指南 WORD版
OpenMP多线程编程指南 WORD版

本文档主要讲述的是OpenMP多线程编程指南;OpenMP是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多线程程序设计的一套指导性注释(Compiler Directive)。OpenMP是一种面向共享内存以及分布式共享内存的多处理器多线程并行编程语言,能被用于显示指导多线程、共享内存并行的应用程序编程接口。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

下载

线程退出后资源未清理:pthread_join 不是可选的

调用 pthread_create 后不调用 pthread_join,线程变成“分离状态”以外的“可连接线程”(joinable)。这类线程结束后,其退出状态、栈内存等资源不会自动释放,直到有其他线程调用 pthread_join。长期运行的程序若漏掉 pthread_join,会持续泄漏资源,最终 pthread_create 返回 EAGAIN(资源耗尽)。

两种处理路径:

  • 主控线程明确等待子线程结束:创建后立刻或适当时机调用 pthread_join(tid, &retval)
  • 子线程自行分离:在子线程函数开头调用 pthread_detach(pthread_self()),之后无需 join;但要注意,分离后不能再被 join,也不能获取其返回值
  • 切勿在主线程 exit() 前遗漏 join —— exit 会终止整个进程,未 join 的 joinable 线程资源仍不释放

信号与多线程交互极易出错,尽量避开 pthread_kill

pthread_kill(tid, SIGUSR1) 向某线程发信号,看似精准,实际风险极高:信号可能被任意线程接收(取决于信号掩码和调度),且若目标线程正阻塞在 readpthread_cond_wait 上,行为不可控;更严重的是,signal 处理函数是全局的,多个线程同时收到同信号,会共用同一个 handler,引发数据竞争。

替代方案更可靠:

  • pthread_cond_signal + pthread_mutex_t 实现线程间通知(推荐)
  • 用管道(pipe)或 eventfd(Linux)做跨线程事件通信,主循环用 poll 等待
  • 真需要信号,应使用 sigwait 在指定线程中同步等待,且提前用 pthread_sigmask 屏蔽其他线程接收该信号

信号与线程模型本身不正交,C 标准库对多线程信号的支持非常有限,能不用就别碰。

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

400

2023.06.20

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

619

2023.07.25

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

354

2023.08.02

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

259

2023.08.09

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

603

2023.09.05

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

527

2023.09.20

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

645

2023.09.20

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

602

2023.09.22

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

58

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.7万人学习

Git 教程
Git 教程

共21课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号