多线程开发常见问题¶
Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.
任务创建应该用哪个接口?¶
优先使用:
qosa_task_create
在明确需要自管栈和TCB内存时,考虑:
qosa_task_create_static
静态创建适合:
对内存可控性要求很高
需要避免动态分配
想把线程内存放到指定区域
静态创建有额外约束:
需要提供 stackMem
tcbMem 需要满足最小大小和对齐要求
SDK提供了配套查询接口:
qosa_task_get_tcb_min_size
qosa_task_get_tcb_align
线程栈多大合适?¶
建议大小:
QCM monitor task栈:2048
最后根据实际业务调整
优先级应该怎么选?¶
默认档位是:
QOSA_PRIORITY_REALTIME = 99
QOSA_PRIORITY_HIGH = 80
QOSA_PRIORITY_ABOVE_NORMAL = 60
QOSA_PRIORITY_NORMAL = 40
QOSA_PRIORITY_BELOW_NORMAL = 20
QOSA_PRIORITY_LOW = 10
QOSA_PRIORITY_IDLE = 1
推荐做法:
常规业务线程用 QOSA_PRIORITY_NORMAL
对时延敏感但不是中断级别的线程用 QOSA_PRIORITY_ABOVE_NORMAL
后台清理、低频处理线程用 QOSA_PRIORITY_BELOW_NORMAL 或 QOSA_PRIORITY_LOW
不要轻易把业务线程拉到 QOSA_PRIORITY_REALTIME 或 QOSA_PRIORITY_HIGH
为什么线程创建成功,但系统表现越来越卡?¶
高优先级线程里做了阻塞I/O
while死循环里没有等待点
反复轮询状态,没有用信号量或消息队列
持锁时间太长
在中心线程或回调线程里做耗时业务
互斥锁、信号量、消息队列、事件标志应该怎么选?¶
互斥锁¶
适合保护共享资源,例如:
全局链表
会话表
状态机上下文
文件句柄集合
信号量¶
适合做同步通知,例如:
一个线程等另一个线程完成初始化
中断或回调通知工作线程继续处理
SDK注释里对 qosa_sem_create 的建议明确:
initialCount 通常设为 0
消息队列¶
适合跨线程传递事件和数据。
例如socket、NTP、MQTT、WebSocket、DTLS重传。
事件标志¶
等任一事件发生
等全部事件准备完成
为什么消息队列发送会失败?¶
qosa_msgq_release 头文件里已经明确说明:
队列满时,发布可能失败并返回负值
高频错误场景:
使用 QOSA_NO_WAIT 发送,但消费者处理不过来
队列深度太小
消费线程被更高优先级线程长期压制
把大对象当消息反复投递,处理路径太慢
建议:
高频路径优先只投递轻量事件结构。
根据峰值流量合理放大 maxNumber。
对关键消息检查返回值,不能默认忽略。
如果发送方不能阻塞,要设计丢弃策略和统计日志。
为什么加锁后会死锁?¶
忘记解锁¶
lock后中途return
lock后goto error,但error分支没unlock
锁顺序不一致¶
线程A先拿lock1再拿lock2
线程B先拿lock2再拿lock1
持锁做耗时操作¶
网络收发
文件读写
AT命令等待
大块内存处理
在回调或中心线程里嵌套等待¶
看起来只是“等一下结果”,实际可能把系统关键线程卡死。
建议:
全项目统一锁顺序。
持锁区只做最小状态修改。
需要耗时处理时,复制必要数据后尽快解锁。