Я создал цепочку из 4 потоков производитель-потребитель (образуя 4-х шаговый конвейер).К моему изумлению, все четыре потока работают последовательно, а не одновременно !!!То есть второй поток загадочным образом ожидает, пока первый поток полностью не завершит свою работу.Третий поток таинственно ожидает, пока второй поток полностью не завершит работу (и т. Д.).
Становится хуже.Если я помещаю Thread.Sleep (300) в цикл первого производителя, то остальные три потока становятся параллельными и фактически получают процессорное время, как и ожидалось, производя консольный вывод «случайным чередованием», как и ожидалось от многопоточного приложения.Я почти не могу принять идею о том, что «сон» является необходимой частью решения, и все же я вижу, что сон включается именно таким образом в код , написанный Джоном Скитом .
Скажите, пожалуйста, что для достижения параллелизма нет необходимости, или, если это так, то почему ?
Более точная история о моей конкретной цепочке производитель-потребитель выглядитthis:
- Первый поток: в тесном цикле генерирует сообщения «виджетов» как можно быстрее, помещая их в очередь для следующего потока.System.Threading.Timer устанавливается на ~ 100 миллисекунд, когда первый виджет добавляется в очередь.Обратный вызов, запускаемый из таймера, является вторым потоком ...
- Второй поток (запускается из таймера): считывает некоторые или все виджеты из предыдущей очереди.Он отправляет их в другую очередь (для использования третьим потоком).Механизм monitor.Pulse / Wait используется для синхронизации с третьим потоком.
- Третий поток: Блокирует монитор. Подождите, пока не будет вызван monitor.Pulse, затем выберет один элемент изочередь.Один элемент помещается в последнюю очередь, снова с помощью монитора. Импульс по окончании отправки.
- четвертый поток: Блокировка на мониторе. Подождите, пока не будет вызван монитор. Импульс.Виджеты обрабатываются.
Обработка 1 миллиона виджетов по этому конвейеру занимает около 4 минут.Через 4 минуты у ПЛЕНТИЙ будет достаточно времени для планирования трех последних потоков и выполнения некоторой работы одновременно с первым потоком.Но, как я уже сказал, последние три потока выполняются последовательно, если я не введу крошечный сон для первого потока.Это не имеет никакого смысла.
Есть мысли о том, почему это работает таким образом?
ps Пожалуйста, не говорите мне, что длинная цепочка производитель-потребитель, как я описал, может быть сокращена илиустранены.Пожалуйста, поверьте мне (или предположите), что мне нужна такая длинная цепь.:)