一个程序问题
之前写过这样一个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)
linux线程同步浅析——睡眠与唤醒的秘密
最新推荐文章于 2023-03-23 11:34:04 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)