@Rarity7

Как создать асинхронную задачу и в чем ее отличие от потока?

На хабре прочитал статью о потоках Вот ссылка
Вот что я прочел:
5d62d6ebea118079990262.png
5d62d6f3a4274130314806.png
5d62d6fd486ed695974685.png
5d62d704d1134019890572.png
1. Как я понял синхронный однопоточный это стандартный, обычный поток с методами которые выполняются один за другим ?
2. Вот тут я не понял, как это может быть синхронный многопоточный ? Разве многопоточность это не асинронность ?
3. Тут асинхронный однопоточный - как создается асинхронность в одном потоке ?
4. Ну тут тоже самый вопрос, как создается асинхронность ?!? Разве создание нового потока, это не асинхронность ??!
  • Вопрос задан
  • 120 просмотров
Решения вопроса 2
@mikluha
ANSI C, Perl, Erlang. FreeBSD, Linux, Mac OS.
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 запускаем в нескольких потоках, это рационально делать для утилизации нескольких процессоров.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы