问题描述
即使阅读了或我仍然对如何在固有的单线程系统上提供异步调用感到困惑。到目前为止,我将解释我的理解,并指出我的疑虑。
Even after reading http://krondo.com/?p=1209 or Does an asynchronous call always create/call a new thread? I am still confused about how to provide asynchronous calls on an inherently single-threaded system. I will explain my understanding so far and point out my doubts.
我读到的一个例子是描述提供异步处理请求的TCP服务器 - 用户会调用方法,例如 get(回调c)
,稍后会调用回调。现在,我的第一个问题 - 我们已经有两个系统,一个服务器和一个客户端。这不是我的意思,因为事实上我们至少有两个线程 - 一个在服务器端,一个在客户端。
One of the examples I read was describing a TCP server providing asynch processing of requests - a user would call a method e.g. get(Callback c)
and the callback would be invoked some time later. Now, my first issue here - we have already two systems, one server and one client. This is not what I mean, cause in fact we have two threads at least - one in the server and one on the client side.
我读到的另一个例子是JavaScript ,这是具有 Node.js
的单线程异步系统的最突出的例子。我无法理解的是,也许用Java思考,是这样的:如果我执行下面的代码(对于不正确的,可能是恶劣的语法道歉):
The other example I read was JavaScript, as this is the most prominent example of single-threaded asynch system with Node.js
. What I cannot get through my head, maybe thinking in Java terms, is this:If I execute the code below (apologies for incorrect, probably atrocious syntax):
function foo(){
read_file(FIle location, Callback c) //asynchronous call, does not block
//do many things more here, potentially for hours
}
对读取文件的调用执行(sth)并返回,允许我的其余功能执行。因为只有一个线程,即执行我的函数的线程,所以在同一个线程(执行我的东西的唯一一个线程)中,如何从磁盘读取字节?
the call to read file executes (sth) and returns, allowing the rest of my function to execute. Since there is only one thread i.e. the one that is executing my function, how on earth the same thread (the one and only one which is executing my stuff) will ever get to read in the bytes from disk?
基本上,在我看来,我缺少一些基本机制,就像某种类型的循环调度程序一样,本质上是单线程的,可能会将任务拆分为较小的或调用一个多线程的组件,它会产生一个线程并读取该文件。
Basically, it seems to me I am missing some underlying mechanism that is acting like round-robin scheduler of some sort, which is inherently single-threaded and might split the tasks to smaller ones or call into a multiothraded components that would spawn a thread and read the file in.
提前感谢所有评论并指出我在路上的错误。
Thanks in advance for all comments and pointing out my mistakes on the way.
更新:感谢所有回复。帮助我解决这个问题的更多好消息来源是:
Update: Thanks for all responses. Further good sources that helped me out with this are here:
- (.NET)
- (定时器的内在函数)
- http://www.html5rocks.com/en/tutorials/async/deferred/
- http://lostechies.com/johnteague/2012/11/30/node-js-must-know-concepts-asynchrounous/
- http://www.interact-sw.co.uk/iangblog/2004/09/23/threadless (.NET)
- http://ejohn.org/blog/how-javascript-timers-work/ (intrinsics of timers)
- http://www.mobl-lang.org/283/reducing-the-pain-synchronous-asynchronous-programming/
推荐答案
真正的答案是它取决于单线程的含义。
The real answer is that it depends on what you mean by "single thread".
多任务有两种方法:协作和中断驱动。 Cooperative,这是你引用的其他StackOverflow项目所要求的,它要求例程明确放弃处理器的所有权,以便它可以做其他事情。事件驱动系统通常以这种方式设计。优点是管理起来要容易得多,并且避免了大部分冲突访问数据的风险,因为任何时候只有一大块代码在执行。缺点是,因为一次只做一件事,所以一切都必须设计得相当快,或者分解成块(通过显式暂停,如 yield())
call),或者系统将冻结,直到该事件完全处理完毕。
There are two approaches to multitasking: cooperative and interrupt-driven. Cooperative, which is what the other StackOverflow item you cited describes, requires that routines explicitly relinquish ownership of the processor so it can do other things. Event-driven systems are often designed this way. The advantage is that it's a lot easier to administer and avoids most of the risks of conflicting access to data since only one chunk of your code is ever executing at any one time. The disadvantage is that, because only one thing is being done at a time, everything has to either be designed to execute fairly quickly or be broken up into chunks that to so (via explicit pauses like a yield()
call), or the system will appear to freeze until that event has been fully processed.
另一种方法 - 线程或进程 - 主动使处理器远离运行代码块,在完成其他操作时暂停它们。这实现起来要复杂得多,并且需要更加谨慎的编码,因为您现在可能同时访问共享数据结构,但功能更强大 - 做得更好 - 更强大,更灵敏。
The other approach -- threads or processes -- actively takes the processor away from running chunks of code, pausing them while something else is done. This is much more complicated to implement, and requires more care in coding since you now have the risk of simultaneous access to shared data structures, but is much more powerful and -- done right -- much more robust and responsive.
是的,在任何一种情况下都确实涉及调度程序。在以前的版本中,调度程序只是旋转直到事件到达(从操作系统和/或运行时环境传递,这是隐式的另一个线程或进程)并在处理下一个到达之前调度该事件。
Yes, there is indeed a scheduler involved in either case. In the former version the scheduler is just spinning until an event arrives (delivered from the operating system and/or runtime environment, which is implicitly another thread or process) and dispatches that event before handling the next to arrive.
这篇关于使用单个线程进行异步处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!