中止 Linux 轮询

发布于 2024-09-29 20:48:46 字数 293 浏览 9 评论 0原文

我正在将音频混音器从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

-黛色若梦 2024-10-06 20:48:46

如果您使用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 your poll() 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 the SA_RESTART flag. You could use an unused signal like SIGUSR1 or one of the real-time signals. When you want to interrupt the poll() then you send that signal and poll() 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 used sigmask() to block unwanted signals.

等风来 2024-10-06 20:48:46

与管道建议类似的一种解决方案是使用 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.

北笙凉宸 2024-10-06 20:48:46

使用超时并检查退出条件。

while (not exit_condition):
    int poll(struct pollfd *fds, nfds_t nfds, int timeout);

Use the timeout and check the exit condition.

while (not exit_condition):
    int poll(struct pollfd *fds, nfds_t nfds, int timeout);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文