Existe o seu problema. Você precisa reprojetar seu aplicativo para não usar um número insano de threads, que estão competindo entre si por recursos. Veja io_submit()
e amigos sobre como enviar ao kernel uma requisição de IO sem bloquear o encadeamento até que ele seja concluído. Você também pode usar setsockopt()
para definir o tamanho do buffer do kernel para zero, para que ele não perca tempo copiando os dados entre seus buffers e os seus próprios. Obviamente, você precisará fornecer várias solicitações de E / S pendentes ao mesmo tempo, para que, assim que terminar uma, ela já tenha outra para passar para a conclusão. Ao fazer isso, você pode ter um único thread (ou um por núcleo cpu de qualquer forma) gerenciar todo o IO em milhares de conexões sem a sobrecarga de alternar entre milhares de threads.