中止 Linux 轮询
我正在将音频混音器从 Windows 上的 directsound 移植到 Linux 上的 alsa。我正在使用系统调用“poll”轮询 16 个文件描述符。现在我需要能够以某种方式中止轮询。在 Windows 上,我使用 WaitForMultipleObjects 使用事件,当我需要中止等待时,我只需在导致等待返回的事件之一上设置事件。有没有办法在 Linux 中将文件描述符标记为“就绪”,以便轮询返回?
我看过 ppoll 但我不熟悉信号,我不想处理不必要的竞争条件。我的意思是,如果 alsa 可以将文件描述符设置为“就绪”,我也应该能够;)
I am porting an audio mixer from directsound on Windows to alsa on Linux. I am polling on, let's say, 16 file descriptors using the system call "poll". Now i need to be able to abort the polling somehow. On Windows i am using the WaitForMultipleObjects using events and when i need to abort the waiting i just SetEvent on one of the events causing the wait to return. Is there any way to mark a file descriptor in Linux "ready" so that the poll will return?
I have taken a look at ppoll but i am not familiar with signals and i don't want to handle unnecessary race conditions. I mean, if alsa can set the file descriptors to "ready" i should also be able to ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您使用
pipe()
函数创建管道,则可以将输出端添加到poll()
列表中。然后你可以在管道的输入端写入一些内容,你的轮询就会返回。与您的 Windows 版本非常相似。您需要使用异步的东西(例如线程或信号处理程序)才能使其工作。
另一种选择是使用
sigaction()
设置信号处理程序而不使用SA_RESTART
标志。您可以使用未使用的信号,例如SIGUSR1
或实时信号之一。当您想要中断 poll() 时,您发送该信号,poll() 将返回 -1 并将 errno 设置为 EINTR。不同的信号也可能会中断您的
poll()
,除非您使用sigmask()
来阻止不需要的信号。If you make a pipe using the
pipe()
function, you can add the output end into yourpoll()
list. Then you can write something into the input end of the pipe and your poll will return. Much like your Windows version.You'd need to be using something asynchronous like threads or signal handlers to make that work.
Another option would be to use
sigaction()
to set a signal handler without theSA_RESTART
flag. You could use an unused signal likeSIGUSR1
or one of the real-time signals. When you want to interrupt thepoll()
then you send that signal andpoll()
will return with -1 and errno set to EINTR.It would be possible for a different signal to interrupt your
poll()
as well, unless you usedsigmask()
to block unwanted signals.与管道建议类似的一种解决方案是使用 Linux 的 eventfd。这种类型的描述符对于向轮询循环添加中止机制非常方便。
请参阅手册页:
https://man7.org/linux/man-pages/man2/ eventfd.2.html
具有描述符可见性(直接或以其他方式)的任何其他线程都可以触发对 eventdfd_write() 的调用,这将在轮询循环中引发 POLLIN 事件。当您捕获该事件时,您可以调用 eventfd_read() 并以您需要的任何方式退出循环。
One solution, similar to the pipe suggestion is to use Linux's eventfd. This type of descriptor is very convenient for adding an abort mechanism to a polling loop.
See the man pages:
https://man7.org/linux/man-pages/man2/eventfd.2.html
Any other thread that has visibility of the descriptor (directly or otherwise) can trigger a call to eventdfd_write() which will cause a POLLIN event in your polling loop. When you catch that event, you call eventfd_read() and exit your loop in whatever manner you need.
使用超时并检查退出条件。
Use the timeout and check the exit condition.