如何处理Rust中的阻塞i / o,或者长期运行外部函数调用 [英] How to handle blocking i/o in Rust, or long running external function calls in general

查看:258
本文介绍了如何处理Rust中的阻塞i / o,或者长期运行外部函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要通过Rust程序中的posix filedescriptor读取外部进程提供的数据。 fd连接保持很长时间(小时),另一方不时将数据传递给我。所以我需要不断地读取和处理数据流。

I need to read data provided by an external process via a posix filedescriptor in my Rust program. The fd connection is kept up a very long time (hours) and the other side passes data to me from time to time. So I need to read and process the data stream continuously.

为此,我编写了一个调用 libc :: read()<的循环/ code>(实际上是readv)读取数据并在收到数据时对其进行处理。因为这会阻塞整个调度程序,所以我在一个新的调度程序上生成一个任务( task :: spawn_sched(SingleThreaded))。只要它运行,这样就可以正常工作,但是我找不到一种方法可以干净地关闭循环。

To do so, I wrote a loop that calls libc::read() (readv actually) to read the data and processes it when received. Since this would block the whole scheduler, I'm spawning a task on a new scheduler (task::spawn_sched(SingleThreaded)). This works fine as long as it runs, but I just can't find a way to cleanly shut down the loop.

由于循环在大多数情况下都是阻塞的,我不能使用port / chan来通知循环退出。

Since the loop is blocking most of the time, I can't use a port/chan to notify the loop to exit.

我试图通过使用失败的链接任务将其删除来杀死循环任务(生成循环任务监督,在其中生成一个链接任务,并在失败之前等待端口上的信号发生!()并用它取消循环任务)。它在测试中运行良好,但 libc :: read()不会被中断(任务在读取完成之前不会失败并且它会命中 task :: yield()在某个时候。

I tried to kill the loop task by taking it down using a failing linked task (spawn the loop task supervised, spawn a linked task within it and wait for a signal on a port to happen before fail!()ing and taking down the loop task with it). It works well in tests, but the libc::read() isn't interrupted (the task doesn't fail before read finishes and it hits task::yield() at some time.

我学到了很多关于libcore来源的知识,但我似乎无法找到一个正确的解决方案。

I learned a lot looking at libcore sources, but I can't seem to find a proper solution.


  1. 有没有办法在Rust中杀死(子)任务,即使它正在执行一些长期的外部函数调用,如阻塞阅读?

  2. 有没有办法在posix filedescriptor上进行非阻塞读取,以便Rust保持对任务的控制?

  3. 我如何做出反应?信号,例如SIGTERM,如果用户终止我的程序。在Rust中似乎没有类似 sigaction()的东西吗?

  1. Is there a way to kill a (child) task in Rust even if it's doing some long external function call like a blocking read?
  2. Is there a way to do nonblocking reads on a posix filedescriptor so that Rust keeps control over the task?
  3. How can I react to signals, e.g. SIGTERM if the user terminates my program. There doesn't seem to be something like sigaction() in Rust yet?


推荐答案


  1. 根据 mozila ,杀死任务是不可能的,现在,更不用说阻止阅读了。

  2. 这将是可能的o在 mozilla / rust / pull / 11410 之后执行此操作,另请参阅我的另一个关于rust-zmq的问题报告 erickt / rust-zmq / issues / 24 这也取决于此。 (对不起这些链接)

  3. 也许信号监听器将适合您。

  1. According to mozila, killing a task is no more possible, for now, let alone blocking read.
  2. It will be possible to do so after mozilla/rust/pull/11410, see also my other issue report for rust-zmq erickt/rust-zmq/issues/24 which also depends on this. (sorry about the links)
  3. Maybe the signal listener will work for you.

这篇关于如何处理Rust中的阻塞i / o,或者长期运行外部函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆