Linux - Использование мьютекса для синхронизации последовательного порта - PullRequest
0 голосов
/ 27 сентября 2018

Я пишу программу на C для ОС Linux.
Программа может запустить таймер: и основная программа, и таймер могут отправлять и получать символы через последовательный порт.
Моя попытка состоит в сериализации последовательного порта.доступ по мьютексу в глобальной структуре, инициализированной при открытии:

if (pthread_mutex_init( &pED->lockSerial, NULL) != 0)
{   
    lwsl_err("lockSerial init failed\n");
}

Я защитил все функции, которые отправляют данные в порт, следующим образом:

ssize_t cmdFirmwareVersion(EngineData *pED)
{
  if (pED->fdSerialPort==-1)
    return -1;

  LOCK_SERIAL;
  unsigned char cmd[] = { 0x00, 0x00, 0x7F };
  write( pED->fdSerialPort, cmd, sizeof(cmd));
  int rx = read ( pED->fdSerialPort, rxbuffer, sizeof rxbuffer);
  dump( rxbuffer, rx);
  UNLOCK_SERIAL;
  return rx;
}

, где

#define LOCK_SERIAL if (0!=pthread_mutex_lock(&pED->lockSerial)) {printf("Err lock");return 0;}
#define UNLOCK_SERIAL   pthread_mutex_unlock(&pED->lockSerial);

Запуск программы и запуск таймера. Я вижу, что запросы выполняются регулярно.Когда я запускаю один из этих вызовов другим способом (из функции веб-сокета rx), программа зависает, и мне нужно ее убить.

Почему вся программа останавливается ??

1 Ответ

0 голосов
/ 04 октября 2018

Если процесс зависает, это может быть из-за циклического ожидания мьютексов или удержания мьютекса и попытки его блокировки снова.Это может привести к взаимоблокировке. Выходные данные

ps будут показывать состояние потока как D или S, если он ожидает ресурс.оно будет отображаться при зависании процесса.

               D    uninterruptible sleep (usually IO)
               S    interruptible sleep (waiting for an event to complete)

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

xxxx@virtualBox:~$ ps -eflT |grep a.out
0 S root      3982  3982  2265  0  80   0 - 22155 -      20:28 pts/0    00:00:00 ./a.out
1 S root      3982  3984  2265  0  80   0 - 22155 -      20:28 pts/0    00:00:00 ./a.out

(gdb) info threads 
  Id   Target Id         Frame 
* 1    Thread 0x7ffff7fdf740 (LWP 4625) "a.out" 0x00007ffff7bbed2d in     __GI___pthread_timedjoin_ex (
    threadid=140737345505024, thread_return=0x0, abstime=0x0, block=    <optimized out>) at pthread_join_common.c:89
  2    Thread 0x7ffff77c4700 (LWP 4629) "a.out" __lll_lock_wait ()
    at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135

Пожалуйста, проверьте блог Tech Easy для получения дополнительной информации о потоках.

...