gpt4 book ai didi

rust - 具有分离的外部和内部可变性的全局静态Vec

转载 作者:行者123 更新时间:2023-12-03 11:39:30 24 4
gpt4 key购买 nike

我有一个代表状态的全局静态Vec。似乎除了全局状态外没有其他解决方案(我正在开发一个可由线程程序用来建立网络连接的库,并且我不希望该程序管理任何内部数据-例如当前打开的套接字)。

我想到的示例(无法编译):

lazy_static! {
static ref SOCKETS: Vec<Connection> = Vec::new();
}

#[no_mangle]
pub extern fn ffi_connect(address: *const u8, length: usize) {
let address_str = unsafe { from_raw_parts(address, length) };
let conn = internal_connect(address_str);
// Now I need to lock all the Vec to mutate it
SOCKETS.push(conn);
}


#[no_mangle]
pub extern fn ffi_recv(index: usize, msg: *mut c_void, size: usize) -> usize {
let buf = unsafe { from_raw_parts(msg as *const u8, size) };
// Now I need to lock ONLY the specific "index" item to mutate it
let conn = SOCKETS.get_mut(index);

conn.read(buf)
}

#[no_mangle]
pub extern fn ffi_send(index: usize, msg: *mut c_void, size: usize) -> usize {
let buf = unsafe { from_raw_parts(msg as *const u8, size) };
// Now I need to lock ONLY the specific "index" item to mutate it
let conn = SOCKETS.get_mut(index);

conn.write(buf)
}

问题是我应该如何实现 SOCKETS以便能够从两个线程调用 ffi_recvffi_send

我在想我必须在Vec外部有一个 RwLock,以便能够在 ffi_connect期间锁定(我不在乎当时是否阻塞),但在 ffi_recvffi_send期间会获得多个不可变的引用。然后,我需要以某种方式获取Vec指向的对象的内部可变性。

我不想在同一对象上同时 ffi_recvffi_send(这必须抛出错误)

最佳答案

我的问题里几乎有答案...

我只需要RwLock<Vec<RwLock<Connection>>>。为了使Vec本身发生变异,外部写锁将被锁定。为了使Vec的项发生变异,RwLock允许多个锁时,外部锁将被读取为阻塞状态。然后,内部RwLock可以被读或写锁定。
ffi_connect变为:

#[no_mangle]
pub extern fn ffi_connect(address: *const u8, length: usize) {
let address_str = unsafe { from_raw_parts(address, length) };
let conn = internal_connect(address_str);

let mut socket_lock = SOCKETS.write().unwrap();
// Nobody can read or write SOCKETS right now
socket_lock.push(conn);
}
ffi_recv变为:

#[no_mangle]
pub extern fn ffi_recv(index: usize, msg: *mut c_void, size: usize) -> usize {
let buf = unsafe { from_raw_parts(msg as *const u8, size) };
// Now I need to lock ONLY the specific "index" item to mutate it
let socket_lock = SOCKETS.read().unwrap();
// SOCKETS can only be "read" locked right now
let mut conn = socket_lock.get(index).write().unwrap();
// Nobody else can read or write to this exact object
// SOCKETS remains readable though!

conn.read(buf)
}

关于rust - 具有分离的外部和内部可变性的全局静态Vec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62352297/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com