libevent это библиотека которая внутри использует тот же select или poll. Библиотека сама по себе не делает код синхронным или асинхронным, все зависит от того, кто эту библиотеку и как применяет.
Не совсем так, внутри libevent использует epoll на Linux и kqueue на MacOS X/FreeBSD, отличия от select есть, и довольно заметные.
При использовании select или poll на вход этой функции передается список файловых дескрипторов, после того, как функция возвращает управление, вызывающий обязан в цикле перебрать все эти дескрипторы и проверить их состояние. Т.е. если к серверу подключены 10000 клиентов, то в ответ на приходящие данные
хотя бы от одного из 10000 клиентов сервер будет проверять состояние всех 10000 подключений, алгоритмическая сложность O(n). epoll и kqueue возвращают список именно тех файловых дескрипторов, состояние которых изменилось, получаем алг.сложность O(1).
Кроме того, между select и poll есть различия, select использует номер файлового дескриптора как индекс в массиве, и если у тебя открыто более 1024 файлов (даже не сокетов, просто обычных файлов достаточно), то приложение, использующее select просто упадет.
Также надо упомянуть и винду, ее API ввода/вывода использует "порты завершения" (IOCP и чуть более оптимизированную реализация с названием RIO начиная с 8.1), поэтому libevent вынужден использовать select под виндой и не может эффективно работать.. nginx это тоже касается

Однопоточный это и есть асинхронный в моем понимании.
Ну вот опять

Есть два подхода к написанию сервера, условно "как нгинкс" и "как апач".
Апач создает новый поток на каждое подключение и захлебывается, когда количество подключений приближается к 1000 или еще раньше. Nginx использует
фиксированное количество потоков (но никак не один, если это специально не указать в конфиге), которые работают в цикле сообщений, используя наиболее эффективный механизм для ОС (см. про epoll и kqueue выше).
На практике, чтобы организовать межпоточное взаимодействие, придется расчехлять блокировки вроде мютексов и в результате код обретет кучу ненужных костылей, а производительность не улучшится, а скорее всего станет хуже по сравнению с асинхронным, однопоточным подходом..
Если блокироваться на мьютексе по приходу данных, как делает Bitcoin Core (да и наверное все остальные клиенты

) и отпускать блокировку по окончания обработки этих данных, то, безусловно, да

А если делать по уму, и синхронизировать только передачу данных между потоками, то приложение будет масштабироваться. Если есть высокие требования к производительности, то можно внедрить lock-free контейнеры... только убедиться, что в данном конкретном случае они дают выигрыш производительности
