gpt4 book ai didi

linux - 如何thread_local!在 rust 中使用动态库?

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

如标题所示,我对共享库如何与rust中的线程局部变量一起使用感到困惑。我在下面有一个最小的例子:

在一个名为minimal_thread_local_example的箱子中:

Cargo.toml:

[package]
name = "minimal_thread_local_example"
version = "0.1.0"
edition = "2018"


[dependencies]
has_thread_local = {path ="./has_thread_local"}
libloading = "0.5"


[workspace]
members = ["shared_library","has_thread_local"]

src/main.rs:
extern crate libloading;


use libloading::{Library, Symbol};
use has_thread_local::{set_thread_local, get_thread_local};

fn main() {
let lib = Library::new("libshared_library.so").unwrap();
set_thread_local(10);
unsafe {
let func: Symbol<unsafe extern fn() -> u32> = lib.get(b"print_local").unwrap();
func();
};
println!("From static executable:{}", get_thread_local());
}


在一个名为 has_thread_local的箱子中:

Cargo.toml:
[package]
name = "has_thread_local"
version = "0.1.0"
edition = "2018"

[lib]

[dependencies]


src/lib.rs:
use std::cell::RefCell;
use std::ops::Deref;


thread_local! {
pub static A_THREAD_LOCAL : RefCell<u64> = RefCell::new(0);
}

pub fn set_thread_local(val: u64) {
A_THREAD_LOCAL.with(|refcell| { refcell.replace(val); })
}

pub fn get_thread_local() -> u64 {
A_THREAD_LOCAL.with(|refcell| *refcell.borrow().deref())
}


在一个名为 shared_library的箱子中:

Cargo.toml:
[package]
name = "shared-library"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]


[dependencies]
has_thread_local = {path = "../has_thread_local"}

src/lib.rs:
use has_thread_local::get_thread_local;

#[no_mangle]
unsafe extern "system" fn print_local() {
println!("From shared library:{}",get_thread_local());
}


Here's a github link for the above.

本质上,我有一个静态可执行文件和一个共享库,并在静态可执行文件中声明了线程局部变量。然后,将该变量设置为10并从共享库和静态可执行文件访问它。

输出:

From shared library:0
From static executable:10

我很困惑为什么要输出(稳定和夜间都发生)。我会想象两者都是10,因为本地线程是在静态可执行文件中声明的,并且只能通过该静态可执行文件中的函数进行访问。我正在寻找一种解释,以了解为什么我会观察这种行为,以及如何使我的本地线程在整个线程中具有相同的值,也就是在共享库和静态库中具有相同的值。

最佳答案

观察到此行为的原因是因为共享库包含它自己依赖的 crate 代码的副本,从而导致两个不同的线程本地声明。
解决方案是将引用传递给有问题的线程本地,而不是直接访问线程本地。有关如何获取对线程本地的引用的更多信息,请参见此处:How to create a thread local variable inside of a Rust struct?

关于linux - 如何thread_local!在 rust 中使用动态库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61116624/

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