Parallel.ForEach и Parallel.For, похоже, ставят элементы в очередь в отдельных потоках.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Гость
 Parallel.ForEach и Parallel.For, похоже, ставят элементы в очередь в отдельных потоках.

Сообщение Гость »


Рассмотрим следующий код:

var items = Enumerable.Range(0, 200); Parallel.ForEach(элементы, элемент => Console.WriteLine(элемент)); Элементы в консоли располагаются в случайном порядке. Я не уверен, как перечисляет Parallel.ForEach, но похоже, что он заранее разделяет настройку на очереди, а затем назначает очередь каждому потоку. Я хочу, чтобы все шло по порядку. Мне не нужно завершение по порядку, я хочу, чтобы элементы, взятые из перечисляемого, были в порядке. Если один поток быстрее, это нормально. Но 8 потоков должны работать всегда и получать элемент только тогда, когда это необходимо.

А теперь попробуем следующее:

var items = Enumerable.Range(0, 200).ToArray(); Parallel.For(0, items.Length, item => Console.WriteLine(item)); Тот же результат, полная случайность. Хорошо, а как насчет этого:

var locker = новый объект(); var items = Enumerable.Range(0, 200).ToArray(); индекс вар = 0; Parallel.For(0, items.Length, _ => { // Выбрасываем индекс, который дал нам параллельный цикл, захватываем // фактический следующий элемент для обработки потокобезопасным способом интервал indexToPull; замок (шкафчик) { indexToPull = индекс++; } Console.WriteLine(пункты[indexToPull]); }); Опять же, случайно. В моем тесте первыми были 0 и 1, но номер 2 находился более чем в середине списка. Теперь я понимаю, что мой пример не идеален, потому что Console.WriteLine на самом деле является результатом завершения параллельного потока. Я просто пытаюсь проиллюстрировать свою точку зрения.

Почему это важно? Для меня обработка элементов занимает от 0,001 секунды до 2+ часов. Я сталкиваюсь с ситуацией, когда я запускаю 8 потоков, используя ParallelOptions, но к концу перечисления количество активных потоков падает и падает. В конце концов, остается 1 поток, но остаются 1-2 необработанных элемента. Таким образом, загрузка процессора снижается и снижается. В самом конце элемент n-2 обрабатывается в единственном оставшемся потоке, но у меня еще есть n-1 и n.

Чего я хочу: я хочу разместить элементы в более или менее порядке сложности и запускать их параллельно. Я хочу, чтобы каждый поток захватывал по одному элементу за раз и всегда получал следующий в списке. Опять же, когда этот поток завершится, не имеет значения. Это должно гарантировать, что 8 потоков все еще выполняются при перечислении последнего элемента. На этом этапе потоки завершатся, и количество запущенных потоков упадет, но элементов не останется, поэтому время, которое я трачу на выполнение менее 8 потоков, сведено к минимуму.
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как текущая очередь, очередь отправки и целевая очередь взаимодействуют друг с другом в GCD?
    Anonymous » » в форуме IOS
    0 Ответы
    102 Просмотры
    Последнее сообщение Anonymous
  • Как преобразовать этот код foreach в Parallel.ForEach?
    Anonymous » » в форуме C#
    0 Ответы
    144 Просмотры
    Последнее сообщение Anonymous
  • Попытка создать кнопки, которые ставят сложность для игры в холст
    Anonymous » » в форуме Html
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • Ошибки регистрации, возникающие в отдельных потоках весной
    Anonymous » » в форуме JAVA
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous
  • В чем разница между картой и forEach в потоках Java в этом случае?
    Anonymous » » в форуме JAVA
    0 Ответы
    54 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»