rust学习(tokio中tcp_stream调用的问题)

问题:

我们涉及了一个socket连接的类,每次收到数据以后,我们都会把tokio::net::TcpStream对应的tcp_stream传递给其他线程。

起初设计如下:

rust 复制代码
pub struct TarNetStream {
    stream:TcpStream, //1
    ...
}

pub trait TarListener {
    fn on_event(&self,event:Event,data:Option<Vec<u8>>,stream:Arc<Box<TarNetStream>>); //2
}

1.stream直接move给TarNetStream

2.回调函数中采用了Arc智能指针

问题1:由于stream被move了,所以多线程编译会直接报错。

改进1:将成员变量变成Arc>(由于stream的read/write都需要mut权限,所以这里需要用refcell)

rust 复制代码
pub struct TarNetStream {
   stream:Arc<RefCell<TcpStream>>,
}

问题2:正常都能使用,但是多线程调用的时候会提示Refcell不能再多线程中使用

改进2:添加mutex锁

rust 复制代码
pub struct TarNetStream {
   stream:Arc<tokio::sync::Mutex<RefCell<TcpStream>>>,
}

问题3:运行直接卡死。原因如下:

rust 复制代码
线程1运行读:
let obj = stream.lock().await;
let result = obj.try_borrow_mut().unwrap().read(&mut buf).await;//1

线程2运行写:
let obj = stream.lock().await;//2
let result = obj.try_borrow_mut().unwrap().write(buf).await;

1.没有数据,这里卡死

2.由于线程1一直在等数据,所以线程2只能在这里2处卡住。

改进4:读写分离

rust 复制代码
pub struct TarNetStream<'a>'> {
    //stream:Arc<RefCell<TcpStream>>,
    read_stream:tokio::sync::Mutex<tokio::net::tcp::ReadHalf<'a'>>>,
    write_stream:tokio::sync::Mutex<WriteHalf<'a'>>>,
    ...
}

问题4:异步线程调用时候编译提示生命周期有问题,应该是ReadHalf/WriteHalf里面存放的是stream的引用,多线程情况下会出现问题,所以直接编译报错?

改进4:移除生命周期,采用OwnerReadHalf/WriteHalf

rust 复制代码
pub struct TarNetStream {
    //stream:Arc<RefCell<TcpStream>>,
    read_stream:tokio::sync::Mutex<tokio::net::tcp::OwnedReadHalf>,
    write_stream:tokio::sync::Mutex<OwnedWriteHalf>,
    ...
}

备考:

如果需要使用OwnedWriteHalf/OwnedReadHalf,需要类似如下的调用:

相关推荐
小辰记事本4 小时前
从零读懂RoCEv2数据包构造:从WQE到线缆上的完整旅程
服务器·网络·网络协议·rdma
辰海Coding4 小时前
MiniSpring框架学习笔记-解决循环依赖的简化IoC容器
笔记·学习
晓梦林5 小时前
cp520靶场学习笔记
android·笔记·学习
北京耐用通信5 小时前
全域适配工业场景耐达讯自动化Modbus TCP 转 PROFIBUS 网关轻松实现以太网与现场总线互通
网络·人工智能·网络协议·自动化·信息与通信
心中有国也有家6 小时前
cann-recipes-infer:昇腾 NPU 推理的“菜谱集合”
经验分享·笔记·学习·算法
Upsy-Daisy6 小时前
AI Agent 项目学习笔记(八):Tool Calling 工具调用机制总览
人工智能·笔记·学习
LuminousCPP7 小时前
数据结构 - 线性表第四篇:C 语言通讯录优化升级全记录(踩坑 + 思考)
c语言·开发语言·数据结构·经验分享·笔记·学习
魔法阵维护师7 小时前
从零开发游戏需要学习的c#模块,第十四章(保存和加载)
学习·游戏·c#
YMWM_8 小时前
UDP协议详解:从原理到Python实践
网络·网络协议·udp
_李小白8 小时前
【android opencv学习笔记】Day 17: 目标追踪(MeanShift)
android·opencv·学习