Rust: core :: marker :: Отправка и необработанные указатели

Созданный на 28 янв. 2015  ·  3Комментарии  ·  Источник: rust-lang/rust

В книге Rust сказано, что необработанные указатели «считаются отправляемыми (если их содержимое считается отправляемым)».

Однако из того, что я вижу, компилятор генерирует ошибку the trait core :: marker :: Send is not implemented for the type когда встречает необработанный указатель на тип Sendable.

Возможно, я делаю что-то не так, может быть, что документация неясна, или может быть, что сообщение об ошибке не помогает указать, в чем заключается реальная проблема с этим кодом.

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);
}

Выдает ошибку:

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)

Самый полезный комментарий

Пример @japaric для Rust 1.25 с использованием NonNull .

https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable

Все 3 Комментарий

Это недавно изменилось, поэтому документы устарели. Спасибо, что заметили и зарегистрировали ошибку!

@drewcrawford Вы можете использовать Unique чтобы сделать ваш необработанный указатель Send доступным. Эта модифицированная версия вашего кода работает:

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 для Rust 1.25 с использованием NonNull .

https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable

Была ли эта страница полезной?
0 / 5 - 0 рейтинги