Как работает thread_local! работа с библиотеками Dynami c в ржавчине? - PullRequest
1 голос
/ 09 апреля 2020

Как видно из названия, я не совсем понимаю, как совместно используемые библиотеки работают с локальными потоками в rust. У меня есть минимальный пример ниже:

В ящике под названием minimal_thread_local_example:

Автомобиль go .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:

Автомобиль go .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:

Автомобиль go .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());
}

Ниже приведена ссылка на github.

По сути, у меня есть исполняемый файл stati c и общая библиотека с локальной переменной потока, объявленной в исполняемом файле stati c. Затем я устанавливаю эту переменную равной 10 и получаю к ней доступ из общей библиотеки и исполняемого файла stati c.

Это выводит:

From shared library:0
From static executable:10

Я не понимаю, почему это выводится ( встречается как в стабильном, так и в ночное время). Я предположил бы, что оба будут равны 10, поскольку локальный поток объявлен в исполняемом файле stati c и доступен только через функции, также расположенные в этом исполняемом файле stati c. Я ищу объяснение того, почему я наблюдаю это поведение и как сделать так, чтобы мой поток имел одинаковое значение во всем потоке, то есть то же самое значение в общей библиотеке и в библиотеке stati c.

...