当我有线程时,是否有非阻塞接收的用例?

发布于 2024-08-29 09:09:45 字数 149 浏览 7 评论 0原文

我知道非阻塞接收在消息传递中使用得不多,但仍然有一些直觉告诉我,它是必要的。以 GUI 事件驱动的应用程序为例,您需要某种方式以非阻塞方式等待消息,以便您的程序可以执行一些计算。解决这个问题的方法之一是使用带有消息队列的特殊线程。是否有一些用例,即使您有线程,您也确实需要非阻塞接收?

I know non-blocking receive is not used as much in message passing, but still some intuition tells me, it is needed. Take for example GUI event driven applications, you need some way to wait for a message in a non-blocking way, so your program can execute some computations. One of the ways to solve this is to have a special thread with message queue. Is there some use case, where you would really need non-blocking receive even if you have threads?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(6

浅沫记忆 2024-09-05 09:09:45

线程的工作方式与非阻塞异步操作不同,尽管通常可以通过使用执行同步操作的线程来实现相同的效果。然而,归根结底,还是如何更有效地处理事情。

线程是有限的资源,应该用于处理长时间运行的活动操作。如果你有一些并不是真正活跃的事情,但需要空闲地等待一段时间才能得到结果(想想网络上的一些 I/O 操作,比如调用 Web 服务或数据库服务器),那么最好使用提供的它的异步替代方案,而不是通过将同步调用放在另一个线程上来不必要地浪费线程。

您可以仔细阅读此问题此处以获取更多理解。

Threads work differently than non-blocking asynchronous operations, although you can usually achieve the same effect by having threads that does synchronous operations. However, in the end, it boils down on how to handle doing things more efficiently.

Threads are limited resources, and should be used to process long running, active operations. If you have something that is not really active doing things, but need to wait idly for some time for the result (think some I/O operation over the network like calling web services or database servers), then it is better to use the provided asynchronous alternative for it instead of wasting threads unnecessarily by putting the synchronous call on another thread.

You can have a good read on this issue here for more understanding.

燃情 2024-09-05 09:09:45

每个连接一个线程通常不是一个好主意(浪费内存,并非​​所有操作系统都具有巨大的线程数,等等)

如何中断阻塞的接收调用?例如,在 Linux 上(也可能在其他一些 POSIX 操作系统上)pthreads + 信号 = 灾难。通过非阻塞接收,您可以多路复用接收套接字上的等待和用于在线程之间通信的某种 IPC 套接字。也相对容易地映射到 Windows 世界。

如果您需要用更复杂的东西(例如 OpenSSL)替换常规套接字,那么依赖阻塞行为可能会给您带来麻烦。例如,OpenSSL 可能会在阻塞套接字上陷入死锁,因为 SSL 协议存在发送者/接收者反转情况,即在完成某些发送之前接收无法继续。

我的经验是——“当有疑问时使用非阻塞套接字”。

One thread per connection is often not a good idea (wasted memory, not all OS are very good with huge thread counts, etc)

How do you interrupt the blocking receive call? On Linux, for example (and probably on some other POSIX OS) pthreads + signals = disaster. With a non-blocking receive you can multiplex your wait on the receiving socket and some kind of IPC socket used to communicate between your threads. Also maps to the Windows world relatively easily.

If you need to replace your regular socket with something more complex (e.g. OpenSSL) relying on the blocking behavior can get you in trouble. OpenSSL, for example, can get deadlocked on a blocking socket, because SSL protocol has sender/receive inversion scenarios where receive can not proceed before some sending is done.

My experience has been -- "when in doubt use non-blocking sockets".

旧情勿念 2024-09-05 09:09:45

对于阻塞 IO,在许多平台上,让应用程序在面对缓慢、挂起或断开连接的客户端/服务时尽最大努力有序关闭是一项挑战。

使用非阻塞 IO,您可以在系统调用返回后立即终止正在进行的操作。如果您的代码在编写时考虑到提前终止(这对于非阻塞 IO 来说相对简单),那么这可以让您优雅地清理已保存的状态。

With blocking IO, it's challenging on many platforms to get your application to do a best effort orderly shutdown in the face of slow, hung, or disconnected clients/services.

With non-blocking IO, you can kill the in-flight operation as soon as the system call returns, which is immediately. If your code is written with premature termination in mind - which is comparatively simple with non-blocking IO - this can allow you to clean up your saved state gracefully.

暖树树初阳… 2024-09-05 09:09:45

我想不出有什么,但有时非阻塞 API 的设计方式使它们比显式多线程实现更容易/更直观地使用。

I can't think of any, but sometimes the non-blocking APIs are designed in a way that makes them easier/more intuitive to use than an explicitly multi-threaded implementation.

执妄 2024-09-05 09:09:45

这是我最近遇到的一个真实情况。以前我有一个每小时运行一次的脚本,由 crontab 管理,但有时用户会登录到计算机并手动运行该脚本。这有一些问题,例如 crontab 和用户并发执行可能会导致问题,有时用户会以 root 身份登录 - 我知道,这是错误的模式,不受我的控制 - 并使用错误的权限运行脚本。因此,我们决定让例程作为守护进程运行,并具有适当的权限,并且用户用来运行的命令现在只会触发守护进程。

因此,这个用户执行的命令基本上会做两件事:触发守护进程并等待它完成任务。但它也需要一个超时,并在等待时继续将守护程序日志转储给用户。

如果我理解您提出的情况,我就有您想要的情况:我需要继续从守护进程监听,同时仍独立与用户交互。解决方案是异步读取。

对我来说幸运的是,我没有考虑使用线程。如果我用 Java 编码,我可能会这么想,但这是 Python 代码。

Here goes a real situation I have faced recently. Formerly I had a script that would run every hour, managed by crontab, but sometimes users would log to the machine and run the script manually. This had some problems, for example concurrent execution by crontab and user could cause problems, and sometimes users would log in as root - I know, bad pattern, not under my control - and run script with wrong permissions. So we decided to have the routine running as daemon, with proper permissions, and the command users were used to run would now just trigger the daemon.

So, this user executed command would basically do two things: trigger the daemon and wait for it to finish the task. But it also needed a timeout and to keep dumping daemon logs to user while waiting.

If I understand the situation you proposed, I had the case you want: I needed to keep listening from daemon while still interacting with user independently. The solution was asynchronous read.

Lucky for me, I didn't think about using threads. I probably would have thought so if I were coding in Java, but this was Python code.

苄①跕圉湢 2024-09-05 09:09:45

我的观点是,当我们认为线程和消息传递是完美的时,真正的权衡是编写调度程序来规划非阻塞接收操作,并为具有共享状态(锁等)的线程编写同步代码。我想说,两者有时很容易,有时又很困难。因此,一个用例是当有许多消息异步消息要接收时,以及当有许多数据要基于消息进行操作时。在使用非阻塞接收的一个线程中,这将非常容易,并且会要求与许多线程和共享状态进行大量同步......我也在考虑一些现实生活中的示例,我可能稍后会包含它。

My point is, that when we consider threads and messaging being perfect, the real trade-off is about writing scheduler for planning the non-blocking receive operations and writing synchronizations codefor threads with shared state (locks etc.). I would say, that both can be sometime easy and sometime hard. So an use case would be when there are many messages asynchronous messages to be received and when there is much data to be operated on based on the messages. This would be quite easy in one thread using non-blocking receive and would ask for much synchronization with many threads and shared state.... I am also thinking about some real life example, I will include it probably later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文