linux线程同步浅析——睡眠与唤醒的秘密

一个程序问题 之前写过这样一个C程序:模块维护一个工作线程、提供一组调用接口(分同步调用和异步调用)。用户调用模块提供的接口后,会向工作队列添加一个任务。然后任务由工作线程来处理。在同步调用情况下,接口调用后调用者被阻塞,等待工作线程处理完成后,将调用者唤醒。伪代码如下: [调用接口] add_command(cmd, pid); /* 1 */raise(S
摘要由CSDN通过智能技术生成

一个程序问题
之前写过这样一个C程序:模块维护一个工作线程、提供一组调用接口(分同步调用和异步调用)。用户调用模块提供的接口后,会向工作队列添加一个任务。然后任务由工作线程来处理。在同步调用情况下,接口调用后调用者被阻塞,等待工作线程处理完成后,将调用者唤醒。伪代码如下:
[调用接口]
add_command(cmd, pid); /* 1 */
raise(SIGSTOP); /* 2 */
get_response(cmd); /* 6 */

[工作线程]
wait_for_command(&cmd, &pid); /* 3 */
do_command(cmd); /* 4 */
kill(pid, SIGCONT); /* 5 */

调用接口向工作队列添加命令以后,向自己发送一个SIGSTOP信号,把自己挂起;工作线程处理命令完成,通过向调用者进程发送SIGCONT信号,将调用者唤醒。
流程上还是比较清晰的,但是有点想当然了。测试发现,程序的执行流程可能变成下面的情况:
[调用接口]
add_command(cmd, pid); /* 1 */
raise(SIGSTOP); /* 5 ... */
get_response(cmd);

[工作线程]
wait_for_command(&cmd, &pid); /* 2 */
do_command(cmd); /* 3 */
kill(pid, SIGCONT); /* 4 */

调用者在添加命令后,发生调度,工作线程在调用者进入睡眠之前,先处理了命令并发出唤醒信号。之后,调用者再睡眠,就没办法被唤醒了。
解决方法
直接使用信号来实现睡眠和唤醒看来是不可取的,于是想到了使用pthread的互斥机制。改写后的程序如下:
[调用接口]
add_command(cmd); /* 1 */
pthread_cond_wait(cond); /* 2 */
get_response(cmd)

  • 0
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值