2015-10-08 4 views
0

Недавно я работал с требованием, в котором существует потребность в многопоточном приложении, чьи потоки выполняются с разной скоростью. вопросы становятся, так как я все еще учусь многопоточность: Сценарий дается положить вещи в перспективе:Многопользовательские темы

Say первый поток работает на 100 Гц «в реальном времени» 2-й серий на 10 Гц

и скажем, что 1-й поток предоставляет данные «myData» во второй поток.

  • Как MyData будет предоставлена ​​2-й нити, является обычной практикой, чтобы просто читать все, что можно из первого потока, или там должны быть какие-то прореживания, чтобы уменьшить скорость.
  • Должен ли myData быть чем-то вроде Singleton с блокирующим механизмом. Хотя myData не является общим, а скорее обновляется первым потоком и используется во втором потоке.
  • Как насчет противоположного случая, когда данные, используемые в одном потоке, должны использоваться с большей скоростью в другом потоке.
+0

Это тот же самый экземпляр 'myData', который используется каждый раз, или вы создаете его новый экземпляр? это 'myData', измененный любым из этих потоков.? Если 'myData' не используется, как вы будете использовать его в обоих протекторах? –

+0

Просто короткое замечание, когда вы заявили, что узнаете о многопоточности, если это не операционная система реального времени, нет никакой гарантии, что нить будет или может работать на частоте 100 Гц, каждые 10 мс ... – ipavlu

+0

Вы пишете «Скажите 1-й поток работает при 100 Гц «в реальном времени» 2-й работает на 10 Гц », и я, честно говоря, даже не понимаю, что это значит. Да, я мог догадаться, но это был бы плохой подход к решению проблем. Не могли бы вы объяснить это немного? –

ответ

1

Как собирается MyData быть предусмотрено на 2-й нити

Один общий метод заключается в создании очереди FIFO - это может быть станд :: Dequeue или связанный список, или независимо от того, и что нить продюсера нажимает элементы данных на один конец очереди, в то время как потребительский поток выталкивает элементы данных с другого конца очереди. Обязательно сериализуйте все обращения к очереди FIFO (используя мьютекс или аналогичный механизм блокировки), чтобы избежать условий гонки.

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

или требуется какой-то прореживание для снижения скорости.

Не требуется никакого прореживания - вторая нить может считывать столько же данных, сколько доступно для чтения, когда она просыпается.

Должен ли myData быть каким-то Синглтоном с блокировкой .

Singleton не является необходимым (хотя это можно сделать так). Механизм блокировки необходим, если у вас нет какого-либо механизма блокировки синхронизации (и если вы задаете этот уровень вопроса, у вас его нет, и вы не хотите пытаться его получить) вещи просто сейчас!)

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

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

+0

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

+0

Выясните, какие элементы данных доступны обоими потоками, и убедитесь, что каждый поток блокирует один и тот же мьютекс перед доступом к этому элементу данных и разблокирует мьютекс после это делается для доступа к элементу данных, так что нет никакой вероятности, что поток B будет читать (или записывать) элемент данных, пока поток A находится в середине записи в элемент данных (или наоборот). (исключение: если элемент данных никогда не изменяется ни одним из потоков, то для этого элемента данных блокировка не требуется) –

0

Любая многопоточная программа должна справляться с возможностью того, что один из потоков будет работать быстрее, чем другой - любым отношением - даже если они выполняются на одном процессоре с той же тактовой частотой.

Ваши варианты включают:

  • производитель-потребитель контейнер, чем позволяет первые данные нити Епдиеие, а второй нитки «поп» его для обработки: вы могли бы позволить очереди расти, как большой, как память позволяет или поставить некоторые ограничения на размере, после чего либо данные были бы потеряны или первый поток будет вынужден замедлить и ждать, чтобы епдиеего дополнительных значений

    • есть библиотеки доступны (например, форсированные), или если вы хотите реализовать его самостоятельно google некоторые учебники/документы на мьютекс и переменных условий
  • сделать что-то концептуально подобное приведенному выше, но где предельного размера составляет 1, так что есть только единственный myData переменных, а не «контейнер» - но все синхронизации и задержка выбор остаются теми же

паттерн Singleton ортогональна к вашим потребностям здесь: два потока должны знать, где эти данные, но, как правило, осуществляется с помощью, например, аргумент указателя на функцию (функции), выполняемую в потоках. Синглтон легко злоупотребляют и лучше избегают, если причины не складываются высоко.

Смежные вопросы