otimizar meu servidor Linux para lidar com 10.000 threads por processo
Como outros explicaram, isso geralmente está errado. Um encadeamento é um recurso dispendioso , principalmente porque possui sua própria pilha de chamadas (normalmente, um megabyte) e porque é uma tarefa agendável pelo kernel. Os threads são ainda mais caros do que os descritores de arquivos abertos .
Leia Sistemas operacionais: Three Easy Pieces (livro didático disponível para download gratuito).
Como regra geral, você não deseja ter muitos threads, e certamente não muitos threads executáveis. O número de threads executáveis geralmente deve ser no máximo o número de núcleos (ou um pequeno múltiplo disso), portanto, cerca de uma dúzia no máximo. O número de threads em um processo pode ser um pouco maior. Portanto, a menos que você tenha um servidor muito expansivo (com muitos soquetes e núcleos de processador), não deseja ter mais de uma dúzia de threads executáveis e cem threads (a maioria deles ociosa) em seu processo (na área de trabalho) .
No Linux, threads e processos são muito semelhantes (já que ambos podem ser criados pelo clone (2) ) e ambos são tarefas agendadas pelo kernel. Na verdade, o agendador do kernel está agendando tarefas que podem ser threads dentro de algum processo com vários threads ou o thread principal único de um processo de thread único (nesse caso, você nomeará "processar" esse único thread) ou threads do kernel. Você provavelmente não deseja ter mais de mil tarefas agendáveis no total no seu sistema de desktop.
No Linux, um processo é simplesmente um grupo de threads compartilhando o mesmo espaço de endereço virtual (e compartilhando outras coisas, como tabela de descritores de arquivos, etc ...). Alguns processos têm apenas um encadeamento.
Um espaço de endereço virtual é definido pela Wikipedia como
"o conjunto de intervalos de endereços virtuais que um sistema operacional disponibiliza para um processo"
(ver igualmente esta resposta explicando que a terminologia não é universal, e alguns documentação Microsoft usa um diferente e incompatível definição).
No Linux, proc (5) é útil para entender o espaço de endereço virtual de alguns processos. Tente ambos
cat /proc/self/maps
e cat /proc/$$/maps
em um terminal. Veja também isso , e pmap (1) e ps (1) e top (1) .
Todos os programas de espaço do usuário estão executando em algum processo e usando memória virtual, portanto, todo processo tem seu próprio espaço de endereço virtual. A RAM física é um recurso gerenciado pelo kernel do Linux, e os aplicativos não têm acesso direto à RAM (exceto pelo mmap (2) -ing /dev/mem
, consulte mem (4) ).
Portanto, um processo não usa diretamente RAM. Ele usa memória virtual e possui seu próprio espaço de endereço virtual. O kernel usa paginação para gerenciar páginas físicas da RAM e fornecer o espaço de endereço virtual e as abstrações do processo . A qualquer momento (mesmo quando seu processo estiver ocioso ou em execução), o kernel poderá paginar algumas páginas (por exemplo, trocá-las no disco). O kernel está configurando o MMU (e lidando com exceções de hardware de falta de página em algum manipulador de interrupções , buscando a página do disco ou propagando uma falha de segmentação para o processo, consulte o sinal (7) )
Você pode ter threads verdes acima dos threads do sistema (mas as bibliotecas de threads verdes são difíceis de implementar e depurar). Veja as goroutines usadas no Go para um exemplo chique. Veja também setcontext (3) .
Às vezes, seu sistema pode experimentar debulhar . Isso acontece quando a memória virtual total (necessária para todos os processos) excede, por um grande fator, a RAM física disponível. Em seguida, seu computador não responde. Leia sobre o tamanho do conjunto residente , paginação por demanda , conjunto de trabalho , comprometimento excessivo de memória , ASLR .
Veja também -for Linux- fork (2) , clone (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , credenciais (7) , pthreads (7) , futex (7) , recursos (7) .