如何在 Rust 中强制恢复被阻止读取文件的线程?

2024-01-03

因为 Rust 没有以非阻塞方式读取文件的内置功能,所以我必须生成一个读取文件的线程/dev/input/fs0为了获得操纵杆事件。假设操纵杆未使用(没有任何内容可读取),因此读取线程在读取文件时被阻塞。

有没有办法让主线程强制恢复读取线程的阻塞读取,以便读取线程可以干净地退出?

在其他语言中,我会简单地关闭主线程中的文件。这将强制恢复阻塞读取。但我在 Rust 中还没有找到这样做的方法,因为读取需要对文件的可变引用。


这个想法是打电话File::read仅当有可用数据时。如果没有可用数据,我们检查一个标志以查看主线程是否请求停止。如果没有,请等待并重试。

这是一个使用的示例nonblock https://crates.io/crates/nonblock crate:

extern crate nonblock;

use std::fs::File;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

use nonblock::NonBlockingReader;

fn main() {
    let f = File::open("/dev/stdin").expect("open failed");
    let mut reader = NonBlockingReader::from_fd(f).expect("from_fd failed");

    let exit = Arc::new(Mutex::new(false));
    let texit = exit.clone();

    println!("start reading, type something and enter");

    thread::spawn(move || {
        let mut buf: Vec<u8> = Vec::new();
        while !*texit.lock().unwrap() {
            let s = reader.read_available(&mut buf).expect("io error");
            if s == 0 {
                if reader.is_eof() {
                    println!("eof");
                    break;
                }
            } else {
                println!("read {:?}", buf);
                buf.clear();
            }
            thread::sleep(Duration::from_millis(200));
        }
        println!("stop reading");
    });

    thread::sleep(Duration::from_secs(5));

    println!("closing file");
    *exit.lock().unwrap() = true;

    thread::sleep(Duration::from_secs(2));
    println!("\"stop reading\" was printed before the main exit!");
}

fn read_async<F>(file: File, fun: F) -> thread::JoinHandle<()>
    where F: Send + 'static + Fn(&Vec<u8>)
{
    let mut reader = NonBlockingReader::from_fd(file).expect("from_fd failed");
    let mut buf: Vec<u8> = Vec::new();
    thread::spawn(move || {
        loop {
            let s = reader.read_available(&mut buf).expect("io error");
            if s == 0 {
                if reader.is_eof() {
                    break;
                }
            } else {
                fun(&buf);
                buf.clear();
            }
            thread::sleep(Duration::from_millis(100));
        }
    })
}

这是一个使用的示例poll http://linux.die.net/man/2/poll的绑定nix https://crates.io/crates/nix箱。功能poll等待(超时)特定事件:

extern crate nix;

use std::io::Read;
use std::os::unix::io::AsRawFd;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

use nix::poll;

fn main() {
    let mut f = std::fs::File::open("/dev/stdin").expect("open failed");
    let mut pfd = poll::PollFd {
        fd: f.as_raw_fd(),
        events: poll::POLLIN, // is there input data?
        revents: poll::EventFlags::empty(),
    };

    let exit = Arc::new(Mutex::new(false));
    let texit = exit.clone();

    println!("start reading, type something and enter");

    thread::spawn(move || {
        let timeout = 100; // millisecs
        let mut s = unsafe { std::slice::from_raw_parts_mut(&mut pfd, 1) };
        let mut buffer = [0u8; 10];
        loop {
            if poll::poll(&mut s, timeout).expect("poll failed") != 0 {
                let s = f.read(&mut buffer).expect("read failed");
                println!("read {:?}", &buffer[..s]);
            }
            if *texit.lock().unwrap() {
                break;
            }
        }
        println!("stop reading");
    });

    thread::sleep(Duration::from_secs(5));

    println!("closing file");
    *exit.lock().unwrap() = true;

    thread::sleep(Duration::from_secs(2));
    println!("\"stop reading\" was printed before the main exit!");

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Rust 中强制恢复被阻止读取文件的线程? 的相关文章

随机推荐

  • 在 StructureMap 中注册一个默认实例

    我有一堂课 MyService 具有静态属性 MyService Context 代表当前上下文 特定于当前登录的用户 因此它会发生变化 我想要实现的目标 ObjectFactory Initialize x gt x For
  • 在 WPF 中,我们如何将 Duration 定义为资源?

    我在许多动画中使用了一个持续时间 0 0 0 5 并且我想仅在一个位置定义该数字 我可以将双精度定义为
  • 在 Win32 API 中绘制格式化文本的最快方法是什么?

    我正在使用普通 Win32 API 在 C 中实现一个文本编辑器 并且我正在尝试找到实现语法突出显示的最佳方法 我知道有像 scintilla 这样的现有控件 但我这样做是为了好玩 所以我想自己完成大部分工作 我还希望它又快又轻 从我到目前
  • TensorFlow 中的高效图像膨胀

    我正在寻找一种有效的实施方式形态学图像膨胀 https en wikipedia org wiki Dilation morphology 在 TensorFlow 中使用方形内核 正如 OpenCV 所示 与实际效果相比 显而易见的方法似
  • 在 React.js 应用程序中从广告合作伙伴加载外部脚本

    我想在我的 React js Web 应用程序中包含两种类型的广告 div div 还有这个广告
  • SQL Server:返回字符串过程 INITCAP

    这就是我所做的 create proc INITCAP string varchar 30 as begin SET string UPPER LEFT string 1 LOWER RIGHT string LEN string 1 en
  • 使用 bootstrap 进行分位数回归的置信区间

    我正在尝试获取线性和分位数回归的五种引导区间 我能够使用 Boot from 引导并找到线性回归的 5 个引导区间 分位数 正常 基本 学生化和 BCa car和 boot ci 来自boot 当我尝试使用 rq 对分位数回归执行相同操作时
  • 使用 Entity Framework 4 时如何返回数据读取器?

    我想使用 LINQ 和 EntityFramework 上下文定义数据库查询 但我不希望返回实体 我想要一个数据读取器 我怎样才能做到这一点 这是为了将行导出到 CSV 干杯 伊恩 如果你需要这个 你很可能正在做一些意想不到的事情 通过查询
  • 理解声明 C 字符串的两种方法[重复]

    这个问题在这里已经有答案了 几周前 我开始学习编程语言 C 我了解 HMTL CSS Javscript PHP 和基本服务器管理等 Web 技术 但 C 语言让我感到困惑 据我了解 C 语言没有字符串数据类型 只有字符数据类型 但我可能是
  • 基本 iPhone 定时器示例

    好吧 我在网上搜索过 甚至在几本书中寻找答案 因为我无法理解 NSTimer 的苹果文档 我正在尝试在同一视图上实现 2 个计时器 每个计时器都有 3 个按钮 开始 停止 重置 第一个计时器从 2 分钟开始倒计时 然后发出蜂鸣声 第二个计时
  • AWS Elastic Beanstalk - 更改 webapp 文件夹的所有者

    我已使用 AWS Elastic Beanstalk 成功创建了一个应用程序 并使用 Git 上传了该应用程序 我剩下要做的就是创建我的settings php 文件 一切都应该可以正常工作 但是 当我使用 ec2 user 用户身份通过
  • Graphviz Dot 中奇怪的边缘位置

    我有一个模块 可以自动输出 以点格式 用某种汇编语言 我的编译器的 IR 编写的函数 节点是使用 记录 形状打印的基本块 问题在于边缘采用了奇怪的路线 例如 digraph node shape record n0 label
  • Apple 智能横幅上的应用程序参数是否会在安装时传递给应用程序?

    我已经为我的应用程序实现了 Apple 智能横幅 其中包含一个应用程序参数 其中包含我希望该应用程序在我的网站上打开的 URL 我以为用户安装应用程序时就会通过 但似乎没有 步骤 用户访问页面 未安装应用程序 单击 查看 转到应用程序商店
  • 如何删除查询中的第一个单词

    如何删除 MySQL 查询中字段的第一个单词 我尝试使用 SUBSTRING INDEX 但没有结果 该字段为varchar 可以同时包含字母和数字 例子 PWS 20110804 Pos 04应该成为20110804 Pos 04 PWS
  • 如何为特定控件创建自己的自定义提示?

    我需要为特定控件 而不是整个应用程序 创建一个自定义提示窗口 具有自己的颜色和布局 提示文本本身不会连接到该特定的Hint财产控制 按照建议 我编写了一个处理程序CM HINTSHOW 如果控件有此功能 则此方法有效ShowHint Tru
  • 找出与 Elastic Beanstalk 应用程序关联的 EC2 实例?

    有没有办法从仪表板找出与我的 Elastic Beanstalk 应用程序关联的 EC2 实例 我检查了 配置 下的每个页面 但找不到有关运行该应用程序的 EC2 实例的任何信息 您无法通过 Elastic Beanstalk 仪表板查看关
  • C++ 一个带有结构数组的类,不知道我需要多大的数组

    我有一个带有字段的类like名字 年龄 学校等 我需要能够存储其他信息 例如他们旅行过的地方以及旅行的年份 我无法专门声明另一个类来保存 TravelDestination 和年份 所以我认为有一个结构体可能是最好的 这只是一个例子 str
  • Java Scanner - 将换行符读取到字符串中?

    我有一个扫描仪 它接受用户输入 直到按 ctrl d 然后是一个 while 循环 将每个单词添加到字符串中 然后打印它 但我想知道如何在字符串中包含像 n 这样的新行指示符凡是有新行的地方 Scanner sc new Scanner S
  • Node.js async.forEach:无法读取未定义的属性“值”

    我有一种感觉 我犯了一个明显的错误 但找不到它 我得到的错误是 node modules async lib async js 194 iterator x value function err v TypeError Cannot rea
  • 如何在 Rust 中强制恢复被阻止读取文件的线程?

    因为 Rust 没有以非阻塞方式读取文件的内置功能 所以我必须生成一个读取文件的线程 dev input fs0为了获得操纵杆事件 假设操纵杆未使用 没有任何内容可读取 因此读取线程在读取文件时被阻塞 有没有办法让主线程强制恢复读取线程的阻