Pelo que entendi, o tamanho da pilha padrão para um pthread no Linux é 16K. Estou obtendo resultados estranhos na minha instalação do Ubuntu de 64 bits.
$ ulimit -s
8192
Além disso:
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &stacksize);
printf("Thread stack size = %d bytes \n", stacksize);
Prints
Thread stack size = 8388608 bytes
Tenho certeza de que o tamanho da pilha não é "8388608". O que pode estar errado?
c
multithreading
Kamath
fonte
fonte
8388608 / 1024 = 8192
.Respostas:
No seu exemplo, o tamanho da pilha é definido como 8388608 bytes, o que corresponde a 8 MB, conforme retornado pelo comando
ulimit -s
Portanto, que corresponde.A partir da
pthread_create()
descrição:Portanto, o tamanho da pilha de encadeamentos pode ser definido através da função set acima ou da
ulimit
propriedade do sistema. Para os 16k aos quais você está se referindo, não está claro em qual plataforma você viu isso e / ou se algum limite de sistema foi definido para isso.Veja a página pthread_create e aqui para alguns exemplos interessantes sobre isso.
fonte
Na verdade, o tamanho da sua pilha virtual é 8388608 bytes (8 MB). Obviamente, é natural concluir que isso não pode estar certo, porque é uma quantidade ridiculamente grande de memória para cada thread consumir para sua pilha quando 99% das vezes alguns KB provavelmente são tudo o que precisam.
A boa notícia é que seu encadeamento usa apenas a quantidade de memória física necessária. Esse é um dos poderes mágicos que o seu sistema operacional obtém ao usar a MMU (Hardware Management Unit) no seu processador. Aqui está o que acontece:
O sistema operacional aloca 8 MB de memória virtual para sua pilha, configurando as tabelas de páginas da MMU para seu encadeamento. Isso requer muito pouca RAM para armazenar apenas as entradas da tabela de páginas.
Quando seu encadeamento é executado e tenta acessar um endereço virtual na pilha que ainda não possui uma página física atribuída, uma exceção de hardware chamada "falha de página" é acionada pela MMU.
O núcleo da CPU responde à exceção de falha de página alternando para um modo de execução privilegiado (que possui sua própria pilha) e chamando a função do manipulador de exceção de falha de página dentro do kernel.
O kernel aloca uma página de RAM física para essa página de memória virtual e retorna ao segmento de espaço do usuário.
O encadeamento de espaço do usuário não vê nada desse trabalho. Do seu ponto de vista, ele apenas usa a pilha como se a memória estivesse lá o tempo todo. Enquanto isso, a pilha cresce automaticamente (ou não) para atender às necessidades do encadeamento.
A MMU é uma parte essencial do hardware dos sistemas de computadores atuais. Em particular, é responsável por grande parte da "mágica" do sistema, por isso recomendo aprender mais sobre o que a MMU faz e sobre a memória virtual em geral. Além disso, se seu aplicativo é sensível ao desempenho e lida com uma quantidade significativa de dados, você deve entender como o TLB (cache da tabela de páginas da MMU) funciona e como você pode reestruturar seus dados ou algoritmos para maximizar sua taxa de acertos no TLB.
fonte