我是 Rust 的新手(我主要在 Node js 中工作)。
我正在创建一个应用程序,我将维护一个类似于 Node.js 的异步系统。因此,带有本地异步执行器的单线程(我不使用 Tokio)。
基本上我依赖这篇文章https://maciej.codes/2022-06-09-local-async.html.
我遇到的问题是当我看到自己使用阻塞函数时。
例如,我想使用nanomsg套接字的阻塞函数read_to_string(但这只是一个例子)。
如果我运行它,我显然会阻塞主线程,从而阻塞应用程序。我可以在单独的线程中运行它,但随后我就失去了使用单线程的优势(需要 Arc 或其他多线程同步来共享数据)。
是否有一种简单的方法可以将任何阻塞函数转换为执行后返回值的 Future,而不阻塞主线程,但不必担心必须直接管理辅助线程并具有“发送”数据结构?
是否有一种简单的方法可以将任何阻塞函数转换为 Future,一旦执行就返回值,而不阻塞主线程,但不必担心必须直接管理辅助线程并具有“发送”数据结构?
听起来你想要鱼与熊掌兼得。 您希望拥有线程,但不必确保程序是线程安全的;您想要 Tokio (
spawn_blocking
) 提供的功能而不使用 Tokio。
说白了:你可以使用线程编码,也可以不使用线程编码。 如果使用线程进行编码,则必须以线程安全的方式进行编码。 如果你想给另一个线程赋值或者从它返回值,这些值的类型必须是
Send
。 如果您想向主线程返回一个值,而主线程可以同时运行其他异步内容,则需要一种线程安全的方式来向主线程发出数据已准备就绪的信号。 这一切都没有办法解决。
如果您想要在线程上运行的任务不需要与程序的其余部分共享任何数据(即,它按值获取输入并按值返回其输入),那么您需要做的就是确保您的输入和输出类型是
Send
;你不需要使用例如Arc
除非您计划线程需要与程序的其他部分共享对该数据的访问。
话虽如此,如果您的目标是“异步”但没有多线程直到您绝对需要它(例如运行阻塞的东西),那么只需在单线程模式下使用 Tokio 。 在此模式下,您仍然可以使用
spawn_blocking
,只要您不通过例如创建新的 Tokio 任务即可。 tokio::spawn
那么你的未来仍然不需要是Send
。