В микроконтроллерах конечно. Вероятно и не доберутся, т.к. сборщик мусора и рантайм. Просто я считаю, что Rust лучше всего подходит для микроконтроллеров, ядра ОС и драйверов. Вобщем тех областей, где нет обычного рантайма, который дает ОС во многих других языках. Кстати, в ядро Linux тоже Rust добавили, и на нем пишут новые драйвера. Так что в 1,5 из этих 3 областей уже мейнстрим. А обычные приложения под Linux, Windows или Android лучше писать на чем-нибудь со сборщиком мусора (имхо).
Тут смотря что считать мейнстримом. Например в области микроконтроллеров без библиотек вендоров (HAL) редко кто пишет. И пару лет назад они начали появляться на Rust. Но кроме того на Rust есть стандартное API HAL (https://github.com/rust-embedded/embedded-hal), чего за все цать лет не удалось создать в других языках.
Фактически под все микроконтроллеры есть библиотеки на С, сильно меньше половины на С++, и сейчас примерно столько же на Rust. Я считаю что это уже мейнстрим.
Попробуйте взять готовую реализацию семафоров на С или С++ (возможно прямо из PostgreSQL), тогда проблема совместимости семафоров точно отпадает. Дальше пишете небольшую обертку на Rust, и используете из библиотеки `shared_memory` только сами функции для расшаривания памяти, но не местные семафоры.
В семафорах уже должны быть атомарные операции с правильными порядком доступа к памяти (Acquire/Release/Seqcst), так что разбираться с этим не придется. Но важно в обертке задействовать RAII, чтобы при окончании работы с указателем автоматически вызывалась функция семафора. Я не знаю, как именно вы хотите работать с семафорами, но для Mutex в Rust принято создавать структуру https://doc.rust-lang.org/std/sync/struct.MutexGuard.html, в деструкторе которой вызывается освобождение Mutex.
В библиотеке написано `A thin wrapper around shared memory system calls`. Если ваш с++ код также написан через системные вызовы, то должно быть всё совместимо. Если же у вас своя реализация семафоров на `atomic_*()`, то надо искать совместимую с ней реализацию Rust через `core::sync::atomic`, и её возможно нет.
Использовать типы Rust, которые имеют такой же макет памяти, как и указатели. Например Option<NonNull<T>> это тоже что и *mut T, но вам компилятор не позволит просто разименовать нулевой указатель.
Только если вы хотите писать код в стиле С на голых указателях. Для типов Option, NonNull, и т.д. никакие проверки даже в unsafe не вуключаются. И абсолютное большинство библиотек не пишут на голых указателях даже при обертывании C API.
Вообще это распространенный предрассудок, что unsafe выключает все проверки. На самом деле он выключает очень маленький набор проверок, например borrow checker работает.
Да, посмотрите на https://embassy.dev/. Асинхронный (async/await) код работы с датчиком MPU6050, с прерываниями и DMA у меня занимает 800 байт RAM (не считая буферов). Микроконтроллер STM32F030.
В nightly уже реализовали const generics (основное обсуждение тут Tracking issue for const generics (RFC 2000)). Теперь не нужно будет дикое шаманство с typenum и generic_array, которыми я активно пользуюсь.
В микроконтроллерах конечно. Вероятно и не доберутся, т.к. сборщик мусора и рантайм.
Просто я считаю, что Rust лучше всего подходит для микроконтроллеров, ядра ОС и драйверов. Вобщем тех областей, где нет обычного рантайма, который дает ОС во многих других языках.
Кстати, в ядро Linux тоже Rust добавили, и на нем пишут новые драйвера. Так что в 1,5 из этих 3 областей уже мейнстрим. А обычные приложения под Linux, Windows или Android лучше писать на чем-нибудь со сборщиком мусора (имхо).
Лучше когда компилятор отлавливает больше ошибок, чем меньше. Вы же не будете с этим спорить?
Тут смотря что считать мейнстримом. Например в области микроконтроллеров без библиотек вендоров (HAL) редко кто пишет. И пару лет назад они начали появляться на Rust.
Но кроме того на Rust есть стандартное API HAL (https://github.com/rust-embedded/embedded-hal), чего за все цать лет не удалось создать в других языках.
Фактически под все микроконтроллеры есть библиотеки на С, сильно меньше половины на С++, и сейчас примерно столько же на Rust. Я считаю что это уже мейнстрим.
Попробуйте взять готовую реализацию семафоров на С или С++ (возможно прямо из PostgreSQL), тогда проблема совместимости семафоров точно отпадает.
Дальше пишете небольшую обертку на Rust, и используете из библиотеки `shared_memory` только сами функции для расшаривания памяти, но не местные семафоры.
В семафорах уже должны быть атомарные операции с правильными порядком доступа к памяти (Acquire/Release/Seqcst), так что разбираться с этим не придется. Но важно в обертке задействовать RAII, чтобы при окончании работы с указателем автоматически вызывалась функция семафора.
Я не знаю, как именно вы хотите работать с семафорами, но для Mutex в Rust принято создавать структуру https://doc.rust-lang.org/std/sync/struct.MutexGuard.html, в деструкторе которой вызывается освобождение Mutex.
В библиотеке написано `A thin wrapper around shared memory system calls`. Если ваш с++ код также написан через системные вызовы, то должно быть всё совместимо.
Если же у вас своя реализация семафоров на `atomic_*()`, то надо искать совместимую с ней реализацию Rust через `core::sync::atomic`, и её возможно нет.
Использовать типы Rust, которые имеют такой же макет памяти, как и указатели. Например Option<NonNull<T>> это тоже что и *mut T, но вам компилятор не позволит просто разименовать нулевой указатель.
Почитайте https://doc.rust-lang.org/nomicon/ffi.html, но вообще FFI в любом языке это сложная тема. Лучше всего использовать готовую библиотеку, в которой всё уже аккуратно написано. Например https://docs.rs/shared_memory/0.12.4/shared_memory/.
P.S. Минусовал не я.
Только если вы хотите писать код в стиле С на голых указателях.
Для типов Option, NonNull, и т.д. никакие проверки даже в unsafe не вуключаются. И абсолютное большинство библиотек не пишут на голых указателях даже при обертывании C API.
Вообще это распространенный предрассудок, что unsafe выключает все проверки. На самом деле он выключает очень маленький набор проверок, например borrow checker работает.
Да, посмотрите на https://embassy.dev/.
Асинхронный (async/await) код работы с датчиком MPU6050, с прерываниями и DMA у меня занимает 800 байт RAM (не считая буферов). Микроконтроллер STM32F030.
Вы распространяете недостоверную информацию. Взять две ссылки на разные элементы внутри вектора можно.
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=c4605e4e02c328af428c7c4f32381424
И это всё требует unsafe, который по определению может вызвать UB. Вот только в реальном коде unsafe почти никогда не нужен.
Добавьте в Cargo.toml, и будет поведение как в debug. Аналогично в debug можно выключить эти проверки.
[profile.release]
overflow-checks = true
Tracking issue for const generics (RFC 2000)). Теперь не нужно будет дикое шаманство с typenum и generic_array, которыми я активно пользуюсь.
Пример выше можно переписать как-то так:
К сожалению, писать реальный код на const generics пока невозможно из-за большого количества ICE (1, 2, 3, ..). Надеюсь скоро исправят.