1. примерно так
2. Нет, многопоточность с асинхронностью не имеет ничего общего. При многопоточности обычно планировщик ядра (если потоки ядерные) переключает контекст между твоими потоками. Работает это так: ты в своем приложении сообщаешь планировщику что хочешь создать поток (например через pthread_create, если ты программируешь в linux или freebsd), указывая ему функцию, которая должна выполняться в отдельном потоке и аргументы для нее. Ядро создает у себя в таблицах запись для него и ставит этот поток в очередь на выполнение так же как основной поток. Адресное пространство у них будет общее.
3. К примеру ты хочешь обслуживать TCP клиентов, ты создаешь сокет (или несколько), ставишь им неблокирующий режим, затем тебе их в цикле нужно опрашивать. Для этого есть несколько способов: select и poll есть во всех ОС, но они хороши когда у тебя сокетов мало. В linux есть еще epoll, который намного более эффективен, во FreeBSD и MacOS есть kqueue - очень эффективный метод. Когда к тебе, к примеру, придет TCP клиент твой select/poll/epoll/kqueue вернет информацию о сокете, который готов для чтения (твой listen сокет), ты делаешь ему accept, и добавляешь сокет клиента в select/poll/epoll/kqueue. Если происходит событие на клиентском сокете, к примеру на нем сработал read - значит там есть данные, ты их читаешь и обрабатываешь, если сработал write - сокет освободился для записи и можно в него писать. Еще в kqueue и epoll есть таймеры. Главное не использовать при такой архитектуре какие-нибудь sleep, не использовать блокирующие библиотеки с базам данных, нужно обраратывать все быстро и возращать управление в select/poll/epoll/kqueue. Если, к примеру, нужно сделать задержку, выполнение коллбэка нужно прервать, создав какой-нибудь таймер (есть много способов).
В целом - разработка асинхронных приложений требует совершенно иного подхода, это обычно немного сложнее, особенно если тебе нужно будет ходить, например, в базу данных. К примеру, системный резолвер (gethostbyname) является блокирующим - его в такое архитектуре исползовать нельзя, придется взять библиотеку, например, c-ares, которая реализует асинхронный резолвер.
4. то же что и 3, но select/poll/epoll/kqueue запускаем в нескольких потоках, это рационально делать для утилизации нескольких процессоров.