Dado este código:
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
DoSomething(someString);
});
Todos os 1000 threads serão gerados quase simultaneamente?
c#
.net
c#-4.0
parallel-processing
Jader Dias
fonte
fonte
Em uma única máquina de núcleo ... Paralelo.ForEach partições (pedaços) da coleção em que está trabalhando entre uma série de threads, mas esse número é calculado com base em um algoritmo que leva em conta e parece monitorar continuamente o trabalho feito pelo threads está alocando para o ForEach. Portanto, se a parte do corpo do ForEach chama funções de bloqueio / vinculação de E / S de longa execução que deixariam o thread esperando, o algoritmo gerará mais threads e reparticionará a coleção entre eles . Se os threads completam rapidamente e não bloqueiam nos threads de IO, por exemplo, como simplesmente calcular alguns números,o algoritmo aumentará (ou mesmo diminuirá) o número de threads até um ponto em que o algoritmo considera o melhor para o rendimento (tempo médio de conclusão de cada iteração) .
Basicamente, o pool de threads por trás de todas as várias funções da biblioteca Parallel, irá trabalhar em um número ótimo de threads a serem usados. O número de núcleos de processador físico constitui apenas parte da equação. NÃO existe uma relação simples de um para um entre o número de núcleos e o número de threads gerados.
Não considero a documentação sobre o cancelamento e o manuseio de threads de sincronização muito útil. Esperançosamente, a MS pode fornecer melhores exemplos no MSDN.
Não se esqueça, o código do corpo deve ser escrito para rodar em vários threads, junto com todas as considerações de segurança de thread usuais, o framework não abstrai esse fator ... ainda.
fonte
Ele calcula um número ideal de threads com base no número de processadores / núcleos. Eles não irão gerar todos de uma vez.
fonte
Consulte O Parallel.For usa uma tarefa por iteração? para ter uma ideia de um "modelo mental" para usar. No entanto, o autor afirma que "No final do dia, é importante lembrar que os detalhes da implementação podem mudar a qualquer momento."
fonte
Ótima pergunta. Em seu exemplo, o nível de paralelização é muito baixo, mesmo em um processador quad core, mas com alguma espera, o nível de paralelização pode ficar muito alto.
Agora veja o que acontece quando uma operação de espera é adicionada para simular uma solicitação HTTP.
Não fiz nenhuma alteração ainda e o nível de simultaneidade / paralelização aumentou drasticamente. A simultaneidade pode ter seu limite aumentado com
ParallelOptions.MaxDegreeOfParallelism
.Eu recomendo configuração
ParallelOptions.MaxDegreeOfParallelism
. Isso não aumentará necessariamente o número de threads em uso, mas garantirá que você inicie apenas um número razoável de threads, o que parece ser sua preocupação.Por último, para responder à sua pergunta, não, você não fará com que todos os tópicos sejam iniciados de uma vez. Use Parallel.Invoke se você deseja invocar em paralelo perfeitamente, por exemplo, testar condições de corrida.
fonte