Rust解决Bug错误“error: future cannot be sent between threads safely”

2023-09-22 10:56:28

介绍:

在开发过程中,我们可能会遇到错误消息: “error: future cannot be sent between threads safely”。这个错误通常是由于使用了不可发送(not Send)的类型引起的,尤其是 std::sync::MutexGuard 类型。这意味着我们不能将一个互斥锁(mutex)在不同线程间进行传递,而 Tokio 运行时又允许任务在每个 .await 点之间在不同线程间移动。因此,我们需要重新组织代码以确保互斥锁的析构函数在 .await 之前运行,以避免出现此错误。

还有另外一种方案是使用 tokio::task::LocalSet。通过使用 LocalSet,你可以确保异步任务只在单个线程上运行,而不需要实现 Send。这对于需要任务始终在同一线程上访问特定资源的情况非常有用。

范例一:

下面我们提供了一个范例来说明可以解决该问题的正确代码和错误代码。

正确代码:

use std::sync::{Mutex, MutexGuard};

async fn ictester_main(mutex: &Mutex<i32>) {
    {
        let mut lock: MutexGuard<i32> = mutex.lock().unwrap();
        *lock += 1;
    } // 在这里,互斥锁的析构函数会在.await之前运行,并释放锁
 
    http_get_request_async().await;
}

错误代码:

use std::sync::{Mutex, MutexGuard};
 
async fn ictester_main(mutex: &Mutex<i32>) {
    let mut lock: MutexGuard<i32> = mutex.lock().unwrap();
    *lock += 1;
    drop(lock); // 这种方式是错误的
 
    http_get_request_async().await;
}

范例二:

另一种解决方案是使用 tokio::task::LocalSet。通过使用 LocalSet,你可以确保异步任务只在单个线程上运行,而不需要实现 Send。这对于需要任务始终在同一线程上访问特定资源的情况非常有用。

use tokio::task::LocalSet;

// ...

let mut local_set = LocalSet::new();
local_set.spawn_local(ictester_main(yourI32Param.clone()));

let out = local_set.await;

在上面的代码中,我们创建了一个 LocalSet,然后使用 spawn_local() 方法将异步任务 ictester_main() 添加到 LocalSet 中。这确保了该任务将在同一线程上运行,从而避免了错误:“error: future cannot be sent between threads safely”。

注意事项

  1. 在使用互斥锁(Mutex)时,务必在任务的关键点上正确释放锁。最佳实践是确保互斥锁的析构函数在.await之前运行,以确保锁被正确释放。可以通过在互斥锁的作用域内使用大括号来控制互斥锁的生命周期。
  2. 避免在异步任务中手动调用drop函数来释放互斥锁。手动调用drop函数会导致互斥锁被提前释放,可能会导致错误,因为互斥锁不应该在异步的上下文中手动释放。
  3. 当使用tokio::task::LocalSet来确保异步任务在同一线程上运行时,需要注意,该方式适用于在同一线程上访问特定资源的情况。

总结:

在解决 “error: future cannot be sent between threads safely” 类似的错误时,我们应该避免将不可发送类型引入跨线程的异步任务中。这可以通过确保互斥锁的析构函数在 .await 之前运行,或者使用 tokio::task::LocalSet 等方法来限制任务的运行范围。通过合理组织代码,我们可以避免这种错误,并确保程序的线程安全性。

除了通过重新组织代码以确保互斥锁在 .await 前释放以避免错误外,还可以使用 tokio::task::LocalSet 来限制异步任务的运行范围。这样可以确保任务始终在同一线程上运行,而无需实现 Send。根据具体情况选择适合的解决方案,以确保代码的正确性和线程安全性。

更多推荐

IT运维:使用数据分析平台监控Windows Eventlog

TIPS:本文鸿鹄版本:2.10.0及以上版本概述本文基于《IT运维:利用鸿鹄采集Windowseventlog数据》(以下简称原文)文章进行了细化与延伸。主要包括细化了安装步骤,增加了仪表板。鸿鹄端配置创建数据集与数据源类型登录鸿鹄提前创建数据集和数据类型,我这里创建的是winlog数据集,下文《安装vector》里

埃文科技受邀出席“安全堤坝”技术论坛

2023年9月11日,2023年国家网络安全宣传周河南省活动开幕式暨河南省网络文明大会在开封博物馆开幕。由CCFYOCSEF郑州举办的“聚焦数据交易监管技术,筑牢数据交易‘安全堤坝’”技术论坛在开封市博物馆二楼会议厅举行。埃文科技总经理王永博士与副总经理武可嘉受邀出席,发表演讲并参与思辨讨论。埃文科技王永博士从“数据流

数据分析思维-分析方法(基础)

数据分析的基础方法概念理解,其关键在于在业务中锻炼数据分析思维。(将以下基础方法带有好奇心的应用在生活中练习数据分析思维)例如:经典的啤酒与尿布(分析一个爸爸去超市买东西的行为,将尿布和啤酒放在一起)例如:分析夜市上100家店那些营业高、利润经营类型等等主要是养成数据分析的思维,可应用工作、生活日常的方方面面。1.象限

Java学习笔记39——网络编程03

TCP通信程序TCP通信程序TCP通信原理TCP发送数据的步骤TCP接收数据的步骤TCP通讯程序练习练习1练习2练习3练习4练习5练习6TCP通信程序TCP通信原理TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通

URL与URI小结

文章目录一、URL是什么?URL的一般形式:二、分类三、URI总结一、URL是什么?每条由Web服务器返回的内容都是和它管理的某个文件相关联的,这些文件中的每一个都有一个唯一的名字,叫做URL(通用资源定位符),是互联网上一种资源的地址。例如:http://www.google.com:80/index.htmlURL

实训笔记——Spark计算框架

实训笔记——Spark计算框架Spark计算框架一、Spark的概述二、Spark的特点三、Spark的安装部署(安装部署Spark的ClusterManager-资源调度管理器的)3.1本地安装--无资源管理器3.2Spark的自带独立调度器Standalone3.2.1主从架构的软件3.2.2Master/work

第26章_瑞萨MCU零基础入门系列教程之独立看门狗定时器-IWDT

本教程基于韦东山百问网出的DShanMCU-RA6M5开发板进行编写,需要的同学可以在这里获取:https://item.taobao.com/item.htm?id=728461040949配套资料获取:https://renesas-docs.100ask.net瑞萨MCU零基础入门系列教程汇总:https://b

在springboot下将mybatis升级为mybatis-plus

在springboot下将mybatis升级为mybatis-plus1.整体描述2.具体步骤2.1更新pom引用2.2更新yml配置2.3更新config配置2.4BaseEntity修改3.程序启动4.总结1.整体描述之前项目工程用的是mybatis,现在需要将其替换为mybatis-plus,mybatis-pl

电商项目高级篇-01 elasticsearch

电商项目高级篇-01elasticsearch1、linux下安装elasticsearch和可视化工具2、docker设置虚拟机开机启动和容器开机启动3、elasticsearch的curd3.1、新增、更新3.2、查询1、linux下安装elasticsearch和可视化工具将安装好jdk1.8和tomcat的ce

使用jmeter+ant+jenkins+git搭建自动化测试平台

最近正在学习自动化测试,于是随手搭建了一下jmeter+ant+jenkins+git平台。接下来,我会按照jdk,jmeter,ant,jenkins,git这个顺序一步一步的搭建起来。一、jdk。这个就不多说了。我用的是1.8版本的,配环境变量网上一大堆。二、jmeter。官网下载:ApacheJMeter-Dow

数据科学的文本技术 Text Technology(IR信息检索、搜索引擎)

一、文章摘要1.内容*IntroductiontoIRandtextprocessing,systemcomponents*Zipf,Heaps,andothertextlaws*Pre-processing:tokenization,normalisation,stemming,stopping.*Indexing:

热文推荐