Le livre Rust dit que les pointeurs bruts "sont considérés comme pouvant être envoyés (si leur contenu est considéré comme pouvant être envoyé)".
Cependant, d'après ce que je peux voir, le compilateur génère l'erreur the trait
core::marker::Send is not implemented for the type
lorsqu'il rencontre un pointeur brut vers un type Sendable.
Il se peut que je fasse quelque chose de mal, il se peut que la documentation ne soit pas claire ou que le message d'erreur ne soit pas utile pour indiquer le véritable problème avec ce code.
extern crate core;
use std::thread::Thread;
struct ShouldBeSendable {
x: i32
}
unsafe impl core::marker::Send for ShouldBeSendable { }
fn main() {
let sendablePtr : *const ShouldBeSendable = &ShouldBeSendable {x: 5};
let closure = move |:| {
*sendablePtr;
};
let something = Thread::spawn(closure);
}
Produit une erreur :
test.rs:15:21: 15:34 error: the trait `core::marker::Send` is not implemented for the type `*const ShouldBeSendable` [E0277]
test.rs:15 let something = Thread::spawn(closure);
^~~~~~~~~~~~~
test.rs:15:21: 15:34 note: `*const ShouldBeSendable` cannot be sent between threads safely
test.rs:15 let something = Thread::spawn(closure);
^~~~~~~~~~~~~
error: aborting due to previous error
$ rustc --version
rustc 1.0.0-dev (d15192317 2015-01-25 16:09:48 +0000)
Cela a changé récemment, laissant les documents obsolètes. Merci d'avoir remarqué et signalé un bogue !
@drewcrawford Vous pouvez utiliser le wrapper Unique
pour rendre votre pointeur brut Send
capable. Cette version modifiée de votre code fonctionne :
use std::ptr::Unique;
use std::thread::Thread;
#[derive(Copy)]
struct ShouldBeSendable {
x: i32
}
unsafe impl std::marker::Send for ShouldBeSendable { }
fn main() {
let ptr : *mut ShouldBeSendable = &mut ShouldBeSendable {x: 5}; // this is not `Send`
let sendablePtr = Unique(ptr); // but this is!
let closure = move |:| {
// `sendablePtr` con be moved inside this closure
let ptr = sendablePtr.0; // unpack the raw pointer
println!("{}", unsafe { (*ptr).x })
};
let something = Thread::scoped(closure).join();
}
@japaric exemple pour Rust 1.25 en utilisant NonNull
.
https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable
Commentaire le plus utile
@japaric exemple pour Rust 1.25 en utilisant
NonNull
.https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable