Несколько переменных, разделяемых между потоками?
У меня есть 4 потока, работающих на ESP32 (двухъядерном ядре):
- 1 поток работает на 1-м ядре, которое связано с Wi-Fi.
- 1 поток работает на 2-м ядре, которое связано с сенсорным экраном.
- 1 поток работает на 2-м ядре, которое связано с дисплеем.
- 1 нить работает на 2-м сердечнике, который связан с датчиками.
Некоторые потоки выполняются почти мгновенно, в то время как, например, тот, который обрабатывает датчики, может занять несколько секунд на взаимодействие, и при этом для остальных потоков не должно происходить никакой блокировки.
Во всяком случае, с ростом программы в передаче данных между ядрами стало участвовать много переменных, и поскольку все это вот-вот будет переделано, у меня есть следующие вопросы, чтобы прояснить для себя ситуацию, так как я нашел довольно много запутанной, даже противоречивой информации в примерах и объяснениях в Интернете:
- Действительно ли ключевого слова "volatile" достаточно для обмена данными между потоками (без ISR)?
- Должен ли "volatile" всегда находиться между"noInterrupts() " и "interrupts()", даже если нет функции ISR?
- Какие подходы следует использовать при обмене большим количеством переменных между потоками (в настоящее время около 40 переменных, но их число, вероятно, будет расти)?
- Блокируется ли xQueueSend / xQueueReceive в случае, если он помещается вокруг всех потоков с разными переменными?
@Yordan Yanakiev, 👍0
Обсуждение1 ответ
Действительно ли ключевое слово "volatile" достаточно для обмена данными между потоками (без ISR)?
Нет - "volatile" просто говорит компилятору, что переменная может изменить значение из-за чего-то другого, чем непосредственно генерируемый код, и сообщает генератору кода, чтобы он не полагался на значение, остающееся статическим, когда он иначе ожидал бы этого. Например, при копировании значения в регистр обычно ожидается, что значение регистра будет продолжать представлять значение переменной в памяти, но если переменная изменчива, это предположение не выполняется. Это будет использоваться, чтобы указать, что ISR может изменить его в любое время; что переменная является входным регистром и может быть изменена извне в любое время; или что другой поток может изменить его, снова, в любое время (предполагая упреждающее многопоточность или многозадачность).
Should "volatile" always be between "noInterrupts()" and "interrupts()", even when there is no ISR function?
No - volatile просто описывает атрибут переменной с течением времени
Какие подходы следует использовать при обмене большим количеством переменных между потоками
Используйте здесь семафор. Поток, который хочет получить доступ к одной из или коллекции общих переменных, запрашивает семафор. RTOS либо возвращает его немедленно, либо (поскольку другой поток уже держит его) приостанавливает задачу до тех пор, пока она не станет доступной, и возвращает ее затем. Поток, удерживающий семафор, может обращаться к переменным (или к любому общему ресурсу, которым управляет этот семафор), а затем возвращает семафор по завершении. Семафоры обычно встроены в ОСРВ.
(Поскольку я не знаком с вашими конкретными ОСРВ, я оставлю ваш четвертый вопрос для тех, кто знаком).
Спасибо Вам за очки, ЖРоберт. Я использую ФРИТОС ( Espriff IDF ), @Yordan Yanakiev
- esp32, platformio A fatal error occurred: Packet content transfer stopped (received 8 bytes) *** [upload] Error 2
- Как выбрать альтернативные контакты I2C на ESP32?
- Драйверы для чипа последовательного порта CH9102X
- Как преобразовать форматированный оператор print в строковую переменную?
- ESP32 - "Детектор Браунаута был активирован" при запуске Wi-Fi
- Питание esp32cam от аккумулятора
- Контакты RX и TX на esp32
- ESP32: отключить детектор отключения питания
вероятно, это произошло во время копирования., @Yordan Yanakiev