Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 异步IO和线程_Multithreading_Asynchronous - Fatal编程技术网

Multithreading 异步IO和线程

Multithreading 异步IO和线程,multithreading,asynchronous,Multithreading,Asynchronous,这是一个概念性的问题,我试图正确理解异步IO和线程是如何共存的 据说,许多lib/框架都有一个限制,即即使它们支持异步操作,它们所依赖的“其他”lib仍在阻塞 例如,Tornado是著名的Python异步web框架和网络库。但是,当您将它与其他组件集成时,您应该确保这些组件也是异步的。因此,例如,您不应该在tornado中使用redis.py,因为它是阻塞的,不会给您异步的好处 另一方面,Node.js有一个很大的优势,即所有内容都是异步的,因此不必处理异步和阻塞lib的混合 现在,我的问题是:

这是一个概念性的问题,我试图正确理解异步IO和线程是如何共存的

据说,许多lib/框架都有一个限制,即即使它们支持异步操作,它们所依赖的“其他”lib仍在阻塞

例如,Tornado是著名的Python异步web框架和网络库。但是,当您将它与其他组件集成时,您应该确保这些组件也是异步的。因此,例如,您不应该在tornado中使用
redis.py
,因为它是阻塞的,不会给您异步的好处

另一方面,Node.js有一个很大的优势,即所有内容都是异步的,因此不必处理异步和阻塞lib的混合

现在,我的问题是:我们不能克服将异步lib和阻塞lib与线程混合的问题吗?我们可以在单独的线程中执行阻塞调用,然后在阻塞调用完成时通知主异步循环

因此,不是在线程中“包装”一个阻塞调用,然后使用某种
wait/notify
构造,从本质上将阻塞调用转换为异步调用吗

我对线程如何使用异步代码的理解仍然很原始,因此请纠正我对此的任何误解

因此,“包装”线程内的阻塞调用,然后使用某种等待/通知构造,本质上将阻塞调用转换为异步调用,这不是吗

这正是No.js的底层基础,它对没有一个非阻塞对应的API(如文件系统操作)做了。

它使用执行这些阻塞操作,并在这些操作完成后通知主事件循环:

libuv提供了一个线程池,可用于运行用户代码并在循环线程中获得通知。该线程池在内部用于运行所有文件系统操作以及getaddrinfo和getnameinfo请求


你的包装建议听起来比实际情况简单得多。对于像python这样的语言,这样做并创建一个单独的执行线程来回调父线程可能很难实现,特别是当您正在编辑一个从未打算这样包装的现有代码库时


不过,我在node.js中看到了一些模块可以实现这一点。例如,该模块没有异步实现(但(我相信有计划改变这一点)),但通过生成子进程,您可以通过回调来模拟这一点。我在实践中看到的这个wrap的具体实现并没有在性能上提供明显的改进,所以这可能就是为什么您没有看到它对最初同步实现的库做了很多工作。

线程的主要问题是每个线程都消耗了大量的核心内存(最多1 MB)无限并行会导致内存耗尽。异步I/O允许每个连接只占用有限的内存,因此允许增加同时连接的数量。代价是限制连接/任务执行阻塞操作,否则会导致内存耗尽


因此,我们的主要目标是限制线程堆栈的内存消耗。您建议使用专用线程池来阻止操作的方式是正确的。我们还可以考虑其他方法,比如使用单线程池来计算和限制并发阻塞任务的数量,但它们更复杂,几乎没有更有效的方法。

这意味着在异步环境中,线程没有任何用处?也就是说,异步程序总是受益于单线程?(例如Nginx)@treecoder我没那么说。线程非常有用,即使在异步环境中也是如此。Node.js进程旨在并行运行以扩大生产规模,但是如果您试图使用线程将同步进程更改为异步进程,那么您应该开始质疑这样做的实际好处。好的,那么同步代码不应该与线程一起变为异步。正确的方法是始终使用epoll/kqueue和family。我说得对吗?如果是这样的话,那么在像python这样的高级语言中,我们应该使用新的
asyncio
模块来实现这一目的?我个人不知道答案,因为我不熟悉这些函数,但在浏览之后,我倾向于说,根据作者的说法,epoll可能无法很好地扩展。同样,我可能是错的,因为我不熟悉。对于更高级的语言,是的,我鼓励使用现有的“asyncify”模块,如果你愿意的话,因为它们擅长概括解决冲突库协同工作的问题。但这仅仅是为了解决库之间的兼容性,而不是为了提高性能。