Pergunta

O que é a diferença entre usar um novo segmento e usando um thread do pool de threads? Quais os benefícios de desempenho estão lá e por que eu deveria considerar o uso de um thread do pool em vez de um que eu criei explicitamente? Estou pensando especificamente da NET aqui, mas exemplos gerais são muito bem.

Foi útil?

Solução

piscina Tópico proporcionará benefícios para operações freqüentes e relativamente curtas por

  • Reutilizar tópicos que já foram criados em vez de criar novos (um processo caro)
  • Regulagem da taxa de criação de thread quando há uma explosão de pedidos de novos itens de trabalho (eu acredito que este é apenas em .NET 3.5)

    • Se você fila 100 tarefas pool de segmentos, ela só vai usar como muitos segmentos como já foram criados para o serviço desses pedidos (digamos, 10 por exemplo). O pool de threads fará verificações freqüentes (eu acredito que cada 500ms em 3,5 SP1) e se não estão na fila de tarefas, ele vai fazer um novo segmento. Se suas tarefas são rápidas, então o número de novos tópicos será pequeno e reutilizar a 10 ou mais tópicos para as tarefas curtas será mais rápido do que criar 100 segmentos na frente.

    • Se a sua carga de trabalho tem consistentemente um grande número de solicitações de pool de thread chegando, então o pool de threads em si sintonia vontade de sua carga de trabalho, criando mais threads na piscina pelo processo acima de modo que haja um número maior de rosca disponível para processar solicitações

    • verificação Aqui para obter mais informações em profundidade sobre como funciona o pool de segmentos sob o capô

A criação de um novo segmento se seria mais apropriado se o trabalho estava indo para ser relativamente longo em execução (provavelmente em torno de um segundo ou dois, mas isso depende da situação específica)

@Krzysztof - tópicos segmento de pool são tópicos de fundo que irá parar quando as principais extremidades da linha. tópicos criados manualmente estão em primeiro plano por padrão (continuará a funcionar após o thread principal terminou), mas pode ser configurado para fundo antes de chamar Iniciar sobre eles.

Outras dicas

O threadpool .NET geridos: -

  • Tamanhos-se com base na carga de trabalho atual e hardware disponível
  • Contém segmentos de trabalho e threads de porta de conclusão (que são usados ??especificamente para o serviço IO)
  • é otimizado para um grande número de operações de duração relativamente curta

Outras implementações pool de segmentos existem que pode ser mais apropriado para operações de longa execução.

Especificamente, use um pool de threads para evitar seu aplicativo de criar muitos threads. A característica mais importante de um pool de threads é a fila de trabalho. Isto é, uma vez que sua máquina é suficientemente agitado, o pool de threads irá fila pedidos em vez de imediatamente gerar mais threads.

Então, se você vai criar um número pequeno, limitado de tópicos criá-los. Se você não pode determinar up-front quantos threads pode ser criado (por exemplo, eles são criados em resposta a IO de entrada), e seu trabalho será de curta duração, use o pool de threads. Se você não sabe quantos, mas seu trabalho vai ser longa, não há nada na plataforma para ajudá-lo -. Mas você pode ser capaz de encontrar implementações ThreadPool alternativas que se encaixam

também

new Thread().Start()

desova Foreground segmento que não vai morrer se você fechar o programa. ThreadPool threads são tópicos de fundo que morrem quando você fechar o aplicativo.

Eu estava curiosa sobre o uso de recursos em relação a estes e e correu uma referência no meu 2012 dual-core Intel i5 laptop usando .NET 4.0 liberação compilação no Windows 8. Pools Tópico assumiu 0.035ms média para começar onde Threads tomou uma média de 5.06ms. Em outras palavras Passe na piscina começou há cerca de 300x mais rápido para um grande número de curtas tópicos duração. Pelo menos na faixa testada (100-2000) tópicos, o tempo total por thread parecia bastante constante.

Este é o código que foi aferido:

    for (int i = 0; i < ThreadCount; i++) {
        Task.Run(() => { });
    }

    for (int i = 0; i < ThreadCount; i++) {
        var t = new Thread(() => { });
        t.Start();
    }

 enter descrição da imagem aqui

Verifique aqui para uma linha mais adiantada:

Quando não devo usar o ThreadPool no .net?

Resumo é que ThreadPool é bom se você precisar gerar muitos tópicos de curta duração, enquanto que usando Threads dá-lhe um pouco mais de controle.

armazenamento local de thread não é uma boa idéia com pools de threads. Dá tópicos uma "identidade"; nem todos os tópicos são mais iguais. Agora rosquear piscinas são especialmente útil se você só precisa de um monte de tópicos idênticos, pronto para fazer o seu trabalho sem sobrecarga criação.

Se você precisar de um monte de tópicos, você provavelmente vai querer usar um ThreadPool. Eles re-uso tópicos poupando-lhe a sobrecarga de criação de threads.

Se você só precisa de um segmento para fazer alguma coisa, Thread é provavelmente mais fácil.

A necessidade primária para theadpool tópicos é lidar com pequenas tarefas curtas que são esperados para completar quase que instantaneamente. Interrupção de hardware manipuladores muitas vezes correr em um contexto de empilhamento que não seria adequado para código não-kernel, mas um hardware interrupção manipulador pode descobrir que um ó conclusão callback / user-mode I deve ser executado o mais rápido possível. Criando um novo segmento para a finalidade de executar tal coisa um seria enorme exagero. Ter alguns tópicos pré-criados que podem ser despachadas para executar E / S retornos de chamada de conclusão ou outras coisas semelhantes é muito mais eficiente.

Um aspecto chave de tais fios é que, se I / métodos de conclusão de sempre completar essencialmente instantaneamente e nunca bloquear, e o número de tais segmentos que estão em execução actualmente tais métodos é pelo menos igual ao número de processadores, a única maneira qualquer outro segmento pode executar antes de um dos métodos acima mencionados acabamentos seria se um dos outros blocos ou métodos seu tempo de execução excede um limite de tempo fatia normal de enfiamento; nenhum deles deve acontecer com muita frequência se o pool de threads é usado como pretendido.

Se um método não se pode esperar para sair dentro de 100ms ou assim de quando se inicia a execução, o método deve ser executado através de alguns outros que o principal pool de threads meios. Se alguém tem um monte de tarefas para executar que são CPU intensivo, mas não vai bloquear, pode ser útil para enviá-los usando um pool de threads do aplicativo (um por núcleo da CPU), que é separado do pool de threads "principal", uma vez usando mais tópicos do que núcleos será contraproducente ao executar tarefas sem bloqueio intensiva da CPU. Se, no entanto, um método vai demorar um segundo ou mais para executar e passará a maior parte de seu tempo bloqueado, o método deve provavelmente ser executado em um segmento dedicado, e deve quase certamente não ser executado em um main-threadpool fio. Se um longa execução necessidades de operação para ser desencadeada por algo como um I / O retorno de chamada, deve-se quer iniciar uma discussão para a operação de longa duração antes do retorno de chamada e tê-lo esperar em um monitor que os pulsos de retorno de chamada, ou então tem o lançamento callback uma nova thread para executar a operação, enquanto as saídas de retorno de chamada, efetivamente retornando a sua própria linha para a threadpool.

Em geral (I nunca utilizado .NET), um pool de threads seria usado para fins de gestão de recursos. Ele permite restrições a serem configurados em seu software. Ele também pode ser feito por motivos de desempenho, como a criação de novos segmentos podem ser caros.

Também pode haver razões específicas do sistema. Em Java (novamente eu não sei se isso se aplica a NET), o gerente dos fios podem ser aplicadas variáveis ??específicas de thread como cada linha é puxada a partir da piscina, e Desativar-los quando eles são devolvidos (forma comum para passar algo como uma identidade).

Exemplo restrição: Eu só tenho 10 conexões db, então eu só permitiria que 10 segmentos de trabalho para acessar o banco de dados.

Isto não significa que você não deve criar seus próprios tópicos, mas existem condições em que faz sentido usar uma piscina.

Usando uma piscina é uma boa idéia, se você não sabe ou não pode controlar quantos discussão será criado.

Basta ter um problema com um formulário usando fio para atualizar algum campo a partir de um banco de dados em um evento PositionChanged de um controle de lista (evite Freez). Ele levou 5 minutos para o meu usuário tenha um erro do banco de dados (muitos conexão com Access) porque ele estava mudando a posição lista muito rápido ...

Eu sei que há outra maneira de resolver o problema de base (incluindo não utilizar acesso), mas pooling é um bom começo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top