代码之家  ›  专栏  ›  技术社区  ›  Fabiano Taioli

管理单线程Rust中的阻塞函数

  •  0
  • Fabiano Taioli  · 技术社区  · 11 月前

    我正在创建一个应用程序,我将维护一个类似于Node的异步系统。因此,一个带有本地异步执行器的单线程(我不使用Tokio)。

    基本上我依赖这个 article on local async executors .

    我遇到的问题是,当我看到自己使用阻塞函数时。

    例如,我想使用阻塞功能 read_to_string nanomsg sockets (但这只是一个例子)。

    如果我运行它,我显然会阻塞主线程,从而阻塞应用程序。我可以在单独的线程中运行它,但这样我就失去了使用单个线程的优势(需要 Arc 或其他多线程同步以共享数据)。

    难道没有一种简单的方法可以将任何阻塞函数转换为 Future 它在执行后返回值,不会阻塞主线程,也不用担心必须直接管理辅助线程和“发送”数据结构?

    1 回复  |  直到 11 月前
        1
  •  2
  •   cdhowie    11 月前

    难道没有一种简单的方法可以将任何阻塞函数转换为Future,在执行后返回值,而不阻塞主线程,也不必担心必须直接管理辅助线程并具有“发送”数据结构吗?

    听起来你想 have your cake and eat it too 。您希望拥有线程,而不必确保程序是线程安全的;你想要东京提供的功能( spawn_blocking )不使用Tokio。

    坦率地说:你可以用线程编码,也可以不用线程编码。如果你用线程编码,你必须以线程安全的方式编码。如果你想给另一个线程赋值或从中返回值,这些值的类型必须是 Send 。如果你想向主线程返回一个值,主线程可以同时运行其他异步内容,你需要一种线程安全的方式来向主线程发出数据准备就绪的信号。 这一切都是无法回避的。

    如果你想在线程上运行的任务不需要与程序的其他部分共享任何数据(也就是说,它按值接收输入并按值返回输出),那么你就不需要 Arc 直接——尽管你仍然需要一种方法来向主线程发出任务已完成的信号。

    话虽如此,如果你的目标是“异步”但没有多线程 直到你绝对需要它 (例如,运行阻塞的东西)然后只是 use Tokio in single-threaded mode 。您仍然可以使用 spawn_blocking 在这种模式下,只要你不通过例如创建新的Tokio任务。 tokio::spawn 那么你的未来仍然不需要 发送 .