Rust 具有分裂外部和内部可变性的全局静态向量机

Rust 具有分裂外部和内部可变性的全局静态向量机,rust,thread-safety,Rust,Thread Safety,我有一个表示状态的全局静态Vec。这似乎是一个全局状态的解决方案(我正在开发一个库,线程程序可以使用它进行网络连接,我不希望程序管理任何内部数据,例如当前打开的套接字) 我想到的示例(未编译): lazy\u static!{ 静态引用套接字:Vec=Vec::new(); } #[没有损坏] 酒吧外部fn ffi_connect(地址:*常数u8,长度:usize){ let address_str=unsafe{from_raw_parts(地址,长度)}; 让conn=内部连接(地址);

我有一个表示状态的全局静态Vec。这似乎是一个全局状态的解决方案(我正在开发一个库,线程程序可以使用它进行网络连接,我不希望程序管理任何内部数据,例如当前打开的套接字)

我想到的示例(未编译):

lazy\u static!{
静态引用套接字:Vec=Vec::new();
}
#[没有损坏]
酒吧外部fn ffi_connect(地址:*常数u8,长度:usize){
let address_str=unsafe{from_raw_parts(地址,长度)};
让conn=内部连接(地址);
//现在我需要锁定所有的Vec来变异它
插座。推动(连接);
}
#[没有损坏]
酒吧外部fn ffi_recv(索引:usize,msg:*mut c_void,大小:usize)->usize{
设buf=unsafe{from_raw_parts(msg as*const u8,size)};
//现在我只需要锁定特定的“索引”项来对其进行变异
设conn=SOCKETS.get_mut(索引);
连接读取(buf)
}
#[没有损坏]
pub extern fn ffi_send(索引:usize,msg:*mut c_void,大小:usize)->usize{
设buf=unsafe{from_raw_parts(msg as*const u8,size)};
//现在我只需要锁定特定的“索引”项来对其进行变异
设conn=SOCKETS.get_mut(索引);
控制写入(buf)
}
问题是我应该如何实现
SOCKETS
,以便能够从两个线程调用
ffi\u recv
ffi\u send

我认为我必须在Vec之外有一个
rBlock
,以便能够在
ffi\u connect
期间锁定(我不在乎在那一点上阻塞),但在
ffi\u recv
ffi\u send
期间获得多个不可变的引用。然后,不知何故,我需要得到向量指向的对象的内部可变性


我不想在同一个对象上同时
ffi\u recv
ffi\u send
(这一定会抛出一个错误)

我的问题里面几乎有了答案

我只需要
rBlock
。为了改变Vec本身,外部写锁将被锁定。为了变异Vec的一个项目,外部锁将被读取阻止,其中RwLock允许多个锁。然后内部RwLock可以被读锁定或写锁定

ffi\u connect
变成:

#[无损坏]
酒吧外部fn ffi_connect(地址:*常数u8,长度:usize){
let address_str=unsafe{from_raw_parts(地址,长度)};
让conn=内部连接(地址);
让mut socket_lock=SOCKETS.write().unwrap();
//现在没有人可以读取或写入套接字
插座/锁推(连接);
}
而ffi_recv变成:

#[无损坏]
酒吧外部fn ffi_recv(索引:usize,msg:*mut c_void,大小:usize)->usize{
设buf=unsafe{from_raw_parts(msg as*const u8,size)};
//现在我只需要锁定特定的“索引”项来对其进行变异
让套接字锁定=SOCKETS.read().unwrap();
//现在只能“读取”锁定套接字
让mut conn=socket_lock.get(index.write().unwrap();
//没有其他人可以读取或写入这个确切的对象
//尽管如此,套接字仍然可读!
连接读取(buf)
}

我的问题里面几乎有答案

我只需要
rBlock
。为了改变Vec本身,外部写锁将被锁定。为了变异Vec的一个项目,外部锁将被读取阻止,其中RwLock允许多个锁。然后内部RwLock可以被读锁定或写锁定

ffi\u connect
变成:

#[无损坏]
酒吧外部fn ffi_connect(地址:*常数u8,长度:usize){
let address_str=unsafe{from_raw_parts(地址,长度)};
让conn=内部连接(地址);
让mut socket_lock=SOCKETS.write().unwrap();
//现在没有人可以读取或写入套接字
插座/锁推(连接);
}
而ffi_recv变成:

#[无损坏]
酒吧外部fn ffi_recv(索引:usize,msg:*mut c_void,大小:usize)->usize{
设buf=unsafe{from_raw_parts(msg as*const u8,size)};
//现在我只需要锁定特定的“索引”项来对其进行变异
让套接字锁定=SOCKETS.read().unwrap();
//现在只能“读取”锁定套接字
让mut conn=socket_lock.get(index.write().unwrap();
//没有其他人可以读取或写入这个确切的对象
//尽管如此,套接字仍然可读!
连接读取(buf)
}

我怀疑内部
rBlock
可能会被
互斥锁所取代(应该使用更少的资源),除非您可以有多个
ffi\u recv
你是对的。你不能有多个
ffi\u recv
,因为即使
read
也需要一个可变的引用。我怀疑内部
rBlock
可能会被
互斥锁所取代(应该使用更少的资源),除非你可以有多个
ffi\u recv
你是对的。您不能有多个
ffi_recv
,因为即使
read
也需要可变的引用