Rp2040: Как сообщить второму ядру от первого ядра в качестве индикатора, чтобы что-то сделать

arduino-nano-rp2040

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

Подход, который я использую в некотором роде грубой силы, выглядит примерно так:

bool indicator = false;
int a,b;

void loop () { // ядро 1
  if(indicator == false){  //проверьте, продолжает ли core2 обработку
     a=random(100);
     b=random(100);
     indicator = true;
  }
}

void loop1(){ // ядро 2
  if(indicator == true){
     int sum = a+b;
     Serial.println(sum);
     indicator == false;
  } 
}

это просто упрощенное представление о том, каким будет мой код. Есть ли лучшие способы сделать это? В общем, я хочу сказать core2 из core1, что ему нужно начать/прекратить что-то делать.

, 👍0


1 ответ


Лучший ответ:

3

То, что вы там создали, называется семафором.

В многопоточном (или многоядерном) программировании существуют две важные концепции сигнализации:

  • Мьютекс - это объект определенной формы, который используется для предоставления доступа к общему ресурсу только одному ядру или потоку одновременно. Поток пытается "заблокировать" мьютекс перед использованием ресурса. Мьютекс может быть "заблокирован" только одним потоком за один раз, и если мьютекс уже заблокирован другим потоком, он может либо заблокировать (он же "спин-замок"), ожидая разблокировки мьютекса, либо он может изящно выйти из строя и повторить попытку позже.
  • Семафор - это простой флаг, который используется для одного потока, чтобы сообщить другому потоку, что что-то произошло или что он должен что-то сделать. Обычно он устанавливается одним потоком, затем считывается и очищается другим потоком.

Как я уже упоминал ранее, семафор-это то, что вы создали, а простое логическое значение-это самый простой семафор, который существует. Однако обратите внимание, что переменная действительно должна быть изменчивой, чтобы компилятор не оптимизировал ее.

В SDK RP2040 встроены некоторые функции, позволяющие ядрам взаимодействовать, в том числе функция "блокировки", позволяющая одному ядру сообщать другому о приостановке до тех пор, пока он не начнет обработку снова, и FIFO, позволяющая асинхронную передачу данных от одного ядра к другому.

,

Даже по прошествии двух дней у меня все еще возникают проблемы с пониманием концепций. Какой из них мне следует использовать? и мьютекс, и семафор, похоже, справляются с этой задачей, но что из этого более правильно?, @DrakeJest

Кроме того , в моем примере я просто использовал базовые типы данных. можно ли заблокировать тип данных класса., @DrakeJest

@DrakeJest Мьютекс используется, когда вы хотите поделиться ресурсом. Например, если у вас есть два потока, которые оба хотят распечатать в последовательном режиме. Один поток "блокирует" мьютекс последовательного порта, печатает то, что ему нужно, а затем снова освобождает его. Другой поток ждет, пока он не сможет заблокировать сам мьютекс перед печатью. Таким образом, вы сохраняете последовательные данные отдельно и не получаете искаженного беспорядка., @Majenko

Семафор используется для того, чтобы просто сообщить другому потоку о том, что что-то произошло. Возможно, поток 1 заполнил буфер данными, и поток 2 должен захватить и обработать эти данные. Или, может быть, поток 1 обнаружил, что что-то произошло на датчике, и хочет сообщить потоку 2, что это произошло., @Majenko

И да, вы можете использовать все, что вам нравится, в качестве семафора или мьютекса. Вам редко нужно что-то большее, чем простой bool или, может быть, int. Если у вас есть класс, вы просто будете использовать bool или int внутри этого класса в качестве семафора/мьютекса., @Majenko