万能的论坛,Linux系统一次等待多个信号量怎么解决?
如题:请教论坛各位大神 ,linux下一次等待多个信号量怎么解决?功能如同window下waitformultipleobjects()函数,一次就可以等待多个信号量。
在linux下多线程编程,linux 下sem_wait()一次只能等待一个信号量。
麻烦哪位高手指点一下 ,不胜感激。 不能嵌套吗? 用eventfd,然后用listen或epoll。 stdio 发表于 2017-2-12 12:14
用eventfd,然后用listen或epoll。
能否 给我发一个程序? 网上找的都是网络并发服务器 ,跟我想要实现的功能不一样。
我需要的功能是: 在主线程A阻塞等待,在线程B , 线程C,线程D 中都可以发信号来唤醒主线程A的阻塞 。 franki 发表于 2017-2-13 10:58
能否 给我发一个程序? 网上找的都是网络并发服务器 ,跟我想要实现的功能不一样。
我需要的功能是: 在 ...
用三个信号量不行吗?
if(sem_wait(semA) || sem_wait(semB) || sem_wait(semC))
{
/* code */
}
franki 发表于 2017-2-13 10:58
能否 给我发一个程序? 网上找的都是网络并发服务器 ,跟我想要实现的功能不一样。
我需要的功能是: 在 ...
那是你自己搞错了写法。
信号量是控制接收方的,不是控制发送方。
所以你等待唯一的一个信号量即可,
3个想唤醒它的都可以给它发送信号,哪个发送了都有效。
redroof 发表于 2017-2-13 11:59
那是你自己搞错了写法。
信号量是控制接收方的,不是控制发送方。
所以你等待唯一的一个信号量即可,
楼上正解,楼主的需求确实不需要那么多信号量。
1个信号量,三个线程发送,一个线程接收即可。 笑笑我笑了 发表于 2017-2-13 11:47
用三个信号量不行吗?
这个好 。谢谢指点!
{:victory:} 笑笑我笑了 发表于 2017-2-13 11:47
用三个信号量不行吗?
sem_wait(semA) || sem_wait(semB) || sem_wait(semC)
这种写法在任何场合下都是错的。
不管你要任何要求,这样写都是错的! sem_wait(semA) || sem_wait(semB) || sem_wait(semC)的写法显然是不行的,同意3楼看法 本帖最后由 笑笑我笑了 于 2017-2-13 19:51 编辑
redroof 发表于 2017-2-13 13:07
sem_wait(semA) || sem_wait(semB) || sem_wait(semC)
这种写法在任何场合下都是错的。
不管你要任何要求 ...
那这个思路还是可取的?改成
if(sem_wait(A) == 0)
{
}
if(sem_wait(B) == 0)
{
}
if(sem_wait(C) == 0)
{
}
笑笑我笑了 发表于 2017-2-13 19:46
那这个思路还是可取的?改成
如果信号量A不被释放,线程永远被阻塞,后面两个if永远不会被执行。 笑笑我笑了 发表于 2017-2-13 11:47
用三个信号量不行吗?
信号量C不被释放,即便A和B释放了线程也是被阻塞的。
阻塞,明白?为什么先是C不解释了。 lswood 发表于 2017-2-13 20:42
信号量C不被释放,即便A和B释放了线程也是被阻塞的。
阻塞,明白?为什么先是C不解释了。 ...
那把 sem_wait 换成 sem_timedwait 就没这个问题了吧。 笑笑我笑了 发表于 2017-2-13 20:50
那把 sem_wait 换成 sem_timedwait 就没这个问题了吧。
如果阻塞线程是要在超时前及时唤醒该如何呢?你这成为时间片轮流查询了。 笑笑我笑了 发表于 2017-2-13 19:46
那这个思路还是可取的?改成
照样错。
除非你就是要求按顺序等待这几个信号量,依次做某些事。
sem_wait(semA) || sem_wait(semB) || sem_wait(semC)跟只等待A完全一样。不带超时的等待总会成功,不成功就挂起自己直到成功为止 redroof 发表于 2017-2-14 08:35
sem_wait(semA) || sem_wait(semB) || sem_wait(semC)跟只等待A完全一样。不带超时的等待总会成功,不成功 ...
那正确的做法应该是什么样的呢? vxworks 下有这个函数可以实现 :
eventReceive(events_Waitfor, EVENTS_WAIT_ANY,WAIT_FOREVER, &events_Recv);
笑笑我笑了 发表于 2017-2-14 08:42
那正确的做法应该是什么样的呢?
如果真的要并行等待多个信号量,而且随便哪个等到了都返回,那么Linux上正确的做法是eventfd加上epoll。 在windows上也很简单啊,直接一个waitformultipleobjects就可以了。各种核心对象都可以同样的等待。
而linux上对信号量的等待只能一次等待一个。可以等待多个的epoll或者select只能等待文件描述符,不能等待信号量。
因此你得用eventfd建立文件描述符来代替信号量,才能并行等待多个。 redroof 发表于 2017-2-14 09:30
在windows上也很简单啊,直接一个waitformultipleobjects就可以了。各种核心对象都可以同样的等待。
而linu ...
请问如何 “用eventfd建立文件描述符来代替信号量 ”,麻烦指点一下 !
不胜感激!{:handshake:} franki 发表于 2017-2-21 16:03
请问如何 “用eventfd建立文件描述符来代替信号量 ”,麻烦指点一下 !
不胜感激!...
搜索 eventfdepoll 就知道了
语义就是正确的“并联”语义,并行等待多个描述符,任何一个有数据了都返回。 redroof 发表于 2017-2-21 21:05
搜索 eventfdepoll 就知道了
语义就是正确的“并联”语义,并行等待多个描述符,任何一个有数据了都返 ...
老大很牛啊,对linux也有研究 参考下libuv的代码 1个信号量就可以,如果需要知道哪个线程发送的,直接用消息队列 first_blood 发表于 2017-2-23 18:37
1个信号量就可以,如果需要知道哪个线程发送的,直接用消息队列
消息队列 是进程间通信 ,多线程里面好像没有这个 。 franki 发表于 2017-2-24 09:00
消息队列 是进程间通信 ,多线程里面好像没有这个 。
“线程之间”相当于是“进程之间”的特例而已。
任何可以用在进程间的通讯方式,在线程之间当然都是可以用的。
页:
[1]