Существует 3 основных подхода.
1. То, что вы имеете ввиду - после accept() создавать отдельный поток на каждого лиента и обрабатывать пришедший коннект в нем.
2. Использовать один поток, переводить сокеты в неблокирующий режим и использовать select() или poll() / epol() / ... для обнаружения данных поступивших в сокет и их обработки
3. Использовать модель с несколькими worker'ами. Запускать несколько потоков-worker'ов работающих так же как в п.2, распределять входящие коннекты между ними. Обычно так пишут серверы для достаточно большой нагрузки.
Достаточно подробный ответ есть здесь:
https://www.opennet.ru/base/faq/prog_faq.txt.html, см. "как писать сервера".