как синхронизировать три зависимых потока - PullRequest
3 голосов
/ 24 января 2012

Если у меня есть

1. mainThread: write data A, 
2. Thread_1: read A and write it to into a Buffer;
3. Thread_2: read from the Buffer.

, как безопасно синхронизировать эти три потока без значительного снижения производительности?Есть ли какое-либо существующее решение для использования?Я использую C / C ++ на Linux.

ВАЖНО: цель - узнать механизм или алгоритмы синхронизации для этого конкретного случая, а не то, как работает мьютекс или семафор.

Ответы [ 3 ]

4 голосов
/ 24 января 2012

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

Во-вторых, если вы решите построить этов любом случае, я бы все-таки серьезно отнесся к тому, чтобы следовать аналогичной модели.Вам не нужно быть надменным в этом вопросе, но я все равно буду думать в первую очередь о структуре данных, в которую один поток записывает данные, а другой - из которых считывает данные.При строгом предпочтении вся необходимая блокировка потока будет встроена в эту структуру данных, поэтому большая часть кода в потоке довольно проста: чтение, обработка и запись данных.Основное отличие от использования обычных каналов Unix состоит в том, что в этом случае вы можете поддерживать данные в более удобном формате, вместо того, чтобы все чтение и запись были в тексте.

Таким образом, то, что я думаю, вы 'в основном это потокобезопасная очередь.При этом почти все остальное становится граничным с тривиальным (по крайней мере, это связано с многопоточностью - такая обработка может и не выполняться, но, по крайней мере, построение ее с несколькими потоками не сильно увеличивает сложность).

1 голос
/ 24 января 2012

Я бы предложил Boost.Thread для этой цели.Это неплохой фреймворк с мьютексами и семафорами, и , он мультиплатформенный. Здесь вы можете найти очень хороший учебник по этому поводу.

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


Редактировать Самым простым решением было бы установить два мьютекса - один на A, а второй на Buffer.Вам не нужно беспокоиться о взаимоблокировках в этом конкретном случае.Просто:

  1. Введите mutex_A с MainThread;Thread1 ожидает освобождения мьютекса.
  2. Оставить мьютекс с MainThread;Thread1 вводит mutex_A и mutex_Buffer, начинает чтение с A и записывает его в Buffer.
  3. Thread1 освобождает оба мьютекса.ThreadMain может вводить mutex_A и записывать данные, а Thread2 может вводить mutex_Buffer безопасно считывать данные из Buffer.

Это, очевидно, самое простое решение, и, вероятно, его можно улучшить, но без дополнительных знаний о проблеме, это лучшее, что я могу придумать.

1 голос
/ 24 января 2012

Трудно сказать, какой у вас опыт работы с потоками C / C ++. Я ненавижу просто указывать на ссылку, но вы читали о pthreads?

https://computing.llnl.gov/tutorials/pthreads/

И для более короткого примера с кодом и простыми mutex'ами (объект блокировки необходимо синхронизировать с данными):

http://students.cs.byu.edu/~cs460ta/cs460/labs/pthreads.html

...