[百度分享]linux线程同步浅析-睡眠与唤醒的秘密.docVIP

  • 2
  • 0
  • 约4.82千字
  • 约 4页
  • 2017-06-08 发布于重庆
  • 举报

[百度分享]linux线程同步浅析-睡眠与唤醒的秘密.doc

[百度分享]linux线程同步浅析-睡眠与唤醒的秘密

一个程序问题? 之前写过这样一个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 ; /* 6 */ [工作线程]? wait_for_command cmd, pid ; /* 3 */ do_command cmd ; /* 4 */ pthread_cond_signal cond ; /* 5 */ 测试发现,这样做就不会出现由于调度而出现“先唤醒、后睡眠”的问题了。? 但是,pthread条件变量是如何避免“先唤醒、后睡眠”的呢?实际上,它依然无法避免调用者在添加命令后,由于调度,造成pthread_cond_signal先于pthread_cond_wait发生的问题。但是条件变量内部记录了信号是否已发生,如果pthread_cond_signal先于pthread_cond_wait,则pthread_cond_wait将看到条件变量中记录的“信号已发生”,于是放弃睡眠。? man一下pthread_cond_signal可以看到如下流程:? [pthread_cond_wait mutex, cond ]? value cond- value; /* 1 */ pthread_mutex_unlock mutex ; /* 2 */ pthread_mutex_lock cond- mutex ; /* 10 */ if value cond- value /* 11 */ ? me- next_cond cond- waiter; ? cond- waiter me; ? pthread_mutex_unlock cond- mutex ; /* X */ ? unable_to_run me ; /* Y */ else pthread_mutex_unlock cond- mutex ; /* 12 */ pthread_mutex_lock mutex ; /* 13 */ [pthread_cond_signal cond ]? pthread_mutex_lock cond- mutex ; /* 3 */ cond- value++; /* 4 */ if cond- waiter /* 5 */ ? sleeper cond- waiter; /* 6 */ ? cond- waiter sleeper- next_cond; /* 7 */ ? able_to_run sleeper ; /* 8 */ pthread_mutex_unlock cond- mutex ; /* 9 */ 这份伪代码中的cond- value就是用于记录“信号已发生”的变量。? 深入一点? 如果你足够细心,可能已经发现上面的pthread的伪代码是有

文档评论(0)

1亿VIP精品文档

相关文档