Создать потокобезопасный глобальный магазин в C - PullRequest
1 голос
/ 11 марта 2019

Я пишу приложение, работающее на FreeRTOS, где у меня есть разные потоки, которые все должны обращаться (читать и записывать) к одним и тем же структурам данных. Поэтому я подумал, что смогу реализовать глобальное хранилище данных, содержащее все данные в некоторых сгруппированных структурах. Я также думал об использовании чего-то вроде SQLite, но я считаю, что это избыточно для моего приложения.

Тем не менее, есть некоторые открытые вопросы

  1. Чтобы гарантировать безопасность потоков, я предполагаю, что мне нужно добавить семафор для доступа для чтения и записи, но ...
  2. Если поток должен обновить только некоторые элементы структуры, мне нужно передать ему указатель на эту структуру, но как только я начну использовать ссылки на указатели, я больше не смогу защитить свой доступ семафором. Итак, как я могу разрешить потоку изменять отдельные элементы структуры без нарушения безопасности потока?
  3. Есть ли лучший способ иметь что-то вроде global store, чем тот, который я планировал использовать? Google не дал много подсказок.

1 Ответ

4 голосов
/ 11 марта 2019

Позвольте мне поделиться с вами наиболее распространенным C-способом для обработки сценариев такого типа.

Чтобы избежать предоставления большого количества глобальных данных, используйте opaque pointer s и получите список API, которые принимают непрозрачный указатель в качестве параметра. Таким образом, вы можете иметь чистый набор API для доступа ко всем вашим структурам, оставляя специфику реализации только в файле .c . Преимущество использования непрозрачного указателя s состоит в том, что никто не знает, как обращаться с типом, указывающим на данные, за исключением API, который принимает непрозрачный указатель в качестве параметра. Это обеспечивает защиту и инкапсуляцию ваших структур, так что они когда-либо получают доступ или изменяются с помощью предоставляемых вами API.

В каждом из определений структуры, определенных непрозрачными указателями, есть mutex ( FreeRTOS имеет мьютекс, реализованный в терминах семафоров ) для доступа к элементам структуры потокобезопасным способом. Вы должны использовать xSemaphoreCreateMutex при создании мьютекса. Во всех ваших API используйте xSemaphoreGive & xSemaphoreTake, когда вы хотите получить доступ к данным члена, которые потенциально доступны для нескольких задач.

...