msgsnd和msgrcv,只有在一下三种情况下,才会退出阻塞状态
- 写或读消息队列成功
- 对应的消息队列被删除
- 信号中断
为了做到超时退出阻塞状态,一般常用的做法是通过alarm,触发信号中断,但是只能是在一个线程的情况下执行。
多线程下调用alarm,SIGALRM信号会传递给其中一个线程(我测试下是传递给主线程…)
我的做法是,写个定时器,由单独的一个线程执行定时器,执行msgsnd和msgrcv的线程需要注册相应的事件到定时器中,由定时器线程通过pthread_kill,向对应线程发送信号,使得msgsnd和msgrcv退出阻塞状态。
2021/09/15 更新
旧方法
- 定时器线程用rbtree + select作为定时器(ms);
- msgsnd/msgrcv前,注册定时器任务,用pipe通知定时器线程;
- 定时器线程超时后,用pthread_kill中断msgsnd/msgrcv线程的阻塞状态。
新方法
- 定时器线程用rbtree + pthread_cond_wait作为定时器(ns);
- msgsnd/msgrcv前,注册定时器任务,用pthread_cond_signal通知定时器线程;
- 定时器线程超时后,用pthread_kill中断msgsnd/msgrcv线程的阻塞状态。
代码在GitHub上
https://github.com/LiuYuguang/MessageQueue