Несколько потоков, вызывающих одну и ту же функцию с помощью периферийной процедуры

У меня есть 2 потока Thread1 и Thread2. И у меня есть функция для периферийного чтения или записи. Произнесите функцию чтения или записи SPI. Оба потока в некоторых случаях используют функции SPI. Поскольку потоки являются параллельными по своей природе, есть ли возможность для обоих потоков попытаться получить доступ к функции одновременно. Это Thread1, который хочет записать 0x10 0x25 в SPI. А The Thread2 хочет записать 0x20 0x56. Если какой-либо механизм синхронизации не используется, существует ли возможность записи неправильной последовательности в буфер SPI?


person SilentCat    schedule 07.03.2014    source источник
comment
Да, такая возможность есть. Вам лучше использовать Mutex здесь!   -  person barak manos    schedule 07.03.2014
comment
т.е. блокировка мьютекса в начале функции и разблокировка в конце обряда функции?   -  person SilentCat    schedule 07.03.2014
comment
Точно. Вызовите Mutex-Get в начале процедуры SPI_Read и Mutex-Put в конце процедуры SPI_Read. Кроме того, инициализируйте этот мьютекс с приоритетом наследования, чтобы он мог разрешать 3-потоковую тупиковую ситуацию с помощью инверсии приоритета.   -  person barak manos    schedule 07.03.2014
comment
вы только что сказали 3-х потоковый тупик.? это опечатка? Я не читаю код SPI как поток. Это просто глобальная функция. Все, что у меня есть, это 2 потока.   -  person SilentCat    schedule 07.03.2014
comment
Не опечатка. Предположим, у вас есть 3 потока с приоритетами High, Med и Low. Теперь предположим, что поток с низким приоритетом выполняет запрос на чтение SPI, тем самым захватывая мьютекс SPI. Затем пробуждается поток со средним приоритетом (по какой-либо причине) и тут же переходит в действие (поскольку его приоритет выше, чем у выполняющегося в данный момент потока). Наконец, поток с высоким приоритетом пробуждается и выполняет запрос чтения SPI. Поскольку мьютекс SPI уже захвачен потоком с низким приоритетом, поток с высоким приоритетом блокируется.   -  person barak manos    schedule 07.03.2014
comment
Таким образом, поток со средним приоритетом предпочтительнее потока с высоким приоритетом. Обратите внимание, что SPI используется только потоком с низким приоритетом и потоком с высоким приоритетом. Нить с приоритетом Мед не имеет к этому никакого отношения. Мьютексы могут решить эту тупиковую ситуацию, используя инверсию приоритета.   -  person barak manos    schedule 07.03.2014
comment
Теперь ясно. . Спасибо @barack manos. .   -  person SilentCat    schedule 07.03.2014


Ответы (2)


Считайте свой SPI общим ресурсом (критическим разделом), который должен быть взаимоисключающим.

Вот общая схема предотвращения переключения контекста во время операций SPI-доступа:

static pthread_mutex_t _mutex;

void SPI_init()
{
    ...
    pthread_mutex_init(&_mutex);
    ...
}

void SPI_read(...)
{
    pthread_mutex_lock(&_mutex);
    ...
    pthread_mutex_unlock(&_mutex);
}


void SPI_write(...)
{
    pthread_mutex_lock(&_mutex);
    ...
    pthread_mutex_unlock(&_mutex);
}
person barak manos    schedule 07.03.2014
comment
Еще кое-что @barack. Вы только что упомянули инициализировать этот мьютекс для наследования приоритета в более старом комментарии. Здесь позаботились об этом - person SilentCat; 07.03.2014
comment
@SilentCat: Нет, это не так. Выше приведена только общая схема. Вам нужно заглянуть в Linux API и найти точные детали для инициализации мьютекса. - person barak manos; 07.03.2014

Темы могут быть запланированы в любом порядке. Итак, да, вы можете записать неправильную последовательность в периферийные регистры.

Так вот, чтобы избежать этого, используйте примитивы синхронизации!

См. базовое руководство по использованию мьютекса: http://www.thegeekstuff.com/2012/05/c-mutex-examples/

person brokenfoot    schedule 07.03.2014
comment
@brockenfoot, не могли бы вы предложить способ избежать этой ситуации? - person SilentCat; 07.03.2014
comment
Проверьте ссылку, которую я разместил. - person brokenfoot; 07.03.2014