Send but not Sync
От: johny5 Новая Зеландия
Дата: 30.11.22 09:42
Оценка:
Вспотыкаюсь вот тут.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4cc7bb7b064c40b5acd79669a72f457c

Мне нужен контейнер для data такой, чтобы он был Send, но необязательно Sync.
Я думаю что могу сделать Arc<Mutex<>>, но мьютекс тут будет как бы оверкилл — данные будут обрабатываться в одном потоке, просто я кидаю работу в другой поток.

Какие ещё "умные указатели" в Расте есть, возможно даже нестандартные?
Отредактировано 30.11.2022 9:46 johny5 . Предыдущая версия .
Re: Send but not Sync
От: ArtDenis Россия  
Дата: 30.11.22 09:53
Оценка: +3
Здравствуйте, johny5, Вы писали:

J>Какие ещё "умные указатели" в Расте есть, возможно даже нестандартные?


Без всяких умных укахателей ты можешь мувать объекты в поток, если они не содержат полей, которые явно запрещены для Send.

fn main() {
    let mut data_for_thread = vec![1, 2, 3];
    for v in &data_for_thread {
        println!("from main v={}", v);
    }

    let thr = std::thread::spawn(move || {
        data_for_thread.push(4);
        for v in &data_for_thread {
            println!("from thread v={}", v);
        }
    });

    thr.join().unwrap();
}
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: Send but not Sync
От: johny5 Новая Зеландия
Дата: 30.11.22 09:59
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Здравствуйте, johny5, Вы писали:


J>>Какие ещё "умные указатели" в Расте есть, возможно даже нестандартные?


AD>Без всяких умных укахателей ты можешь мувать объекты в поток, если они не содержат полей, которые явно запрещены для Send.


Упс, забыл про один аспект, что данные должны быть shared, RefCell<> отлично туда подходил.

И пока писал, понял свою ошибку. Компилятор не может знать что все копии Arc находятся в одном потоке, и потому он требует от контента Sync. Думаю даже если и валяются где смарт поинтеры с таким свойством — они явно будут unsafe, потому что гарантия того, что все копии находятся в одном потоке ложится на плечи программиста.

У меня правда вот такой монстр вышел:
Arc<Mutex<RefCell<>>> — есть ли что то покороче? Структура, которая должна быть доступна из разных объектов (shared_ptr<>), и ещё перемещается в другой поток.
Re[3]: Send but not Sync
От: FR  
Дата: 30.11.22 10:10
Оценка: 5 (1) +1
Здравствуйте, johny5, Вы писали:

J>У меня правда вот такой монстр вышел:

J>Arc<Mutex<RefCell<>>> — есть ли что то покороче? Структура, которая должна быть доступна из разных объектов (shared_ptr<>), и ещё перемещается в другой поток.

А зачем RefCell если уже есть Mutex?
Mutex же тоже дает внутреннюю изменяемость
Re: Send but not Sync
От: flаt  
Дата: 30.11.22 10:19
Оценка: 29 (3)
Здравствуйте, johny5, Вы писали:


J>Вспотыкаюсь вот тут.

J>https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=4cc7bb7b064c40b5acd79669a72f457c

J>Мне нужен контейнер для data такой, чтобы он был Send, но необязательно Sync.

J>Я думаю что могу сделать Arc<Mutex<>>, но мьютекс тут будет как бы оверкилл — данные будут обрабатываться в одном потоке, просто я кидаю работу в другой поток.

https://lib.rs/crates/sendable
Re[3]: Send but not Sync
От: ArtDenis Россия  
Дата: 30.11.22 10:23
Оценка: 5 (1) +2
Здравствуйте, johny5, Вы писали:

J>У меня правда вот такой монстр вышел:

J>Arc<Mutex<RefCell<>>> — есть ли что то покороче? Структура, которая должна быть доступна из разных объектов (shared_ptr<>), и ещё перемещается в другой поток.

Реально монстр. RefCell тут бессмысленный. В растбуке подробно расписано как работать с shared объектами из разных потоков: https://doc.rust-lang.ru/book/ch16-03-shared-state.html#%D0%90%D1%82%D0%BE%D0%BC%D0%B0%D1%80%D0%BD%D1%8B%D0%B9-%D1%81%D1%87%D1%91%D1%82%D1%87%D0%B8%D0%BA-%D1%81%D1%81%D1%8B%D0%BB%D0%BE%D0%BA-arct

Но что-то мне подксказывает, что чтобы бросить объект в поток на обработку достаточно будет отправки сообщений между потоками: https://doc.rust-lang.ru/book/ch16-02-message-passing.html
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.