Асинхронные API

Когда я пытаюсь реализовать асинхронные вызовы API / неблокирующие вызовы, я знаю немного о приложении All Plain-C, которое у меня есть, я читал про APM (модель асинхронного программирования) от «Делегатов». По сути, я хочу вызвать один API f1() для выполнения какой-либо функции (что занимает много времени 8-10 секунд), поэтому я вызываю этот API f1(), забываю об этом и продолжаю выполнять другую работу, например Ввод-вывод для выборки данных для следующего вызова f1() или некоторых функций, не зависящих от результата f1().

Если кто-то использовал эту модель программирования APM, я ищу краткое объяснение реализации неблокирующих вызовов.

Есть ли другой способ реализации асинхронных API-интерфейсов, любая другая библиотека / фреймворк, которые могут в этом помочь?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
2 323
5

Ответы 5

Замените делегатов указателями на функции в C, все остальное в основном такое же, как то, что вы читали.

В основном вам нужно создать многопоточное (или многопроцессорное) приложение. API f1 () должен порождать поток (или процесс) для обработки данных в отдельном пространстве выполнения. По завершении подпрограмма f1 () должна сигнализировать основному процессу, что выполнение выполнено (signal (), очереди сообщений и т. д.).

Популярным способом выполнения асинхронного программирования в простых программах на C является использование «цикла событий». Есть множество библиотек, которые вы можете использовать. Предлагаю взглянуть на бойкий.

Другой альтернативой является использование нескольких упреждающих потоков (по одному для каждой параллельной операции) и их синхронизация с мьютексами и условными переменными. Однако я бы избегал упреждающей потоковой передачи в простом C, особенно если вы хотите писать переносимые программы. Трудно понять, какие библиотечные функции являются реентерабельными, обработка сигналов в многопоточных программах вызывает затруднения, и в целом библиотеки C и системные функции были разработаны для однопоточного использования.

Если вы планируете запускать свое приложение только на одной платформе (например, Windows) и работа, выполняемая с помощью f1 (), является относительно простой вещью, то многопоточность вполне подойдет.

Если функция f1 (), о которой вы говорите, сама по себе не реализована асинхронно, вам нужно будет самостоятельно заключить ее в отдельный поток. При этом нужно быть осторожным в отношении побочных эффектов, которые могут быть вызваны вызовом этой конкретной функции. Многие библиотеки не предназначены для обеспечения потоковой безопасности, и множественные одновременные вызовы функций из таких библиотек приведут к повреждению данных. В таких случаях вам может потребоваться завершить функциональность во внешнем рабочем процессе. Для тяжелой работы, о которой вы упомянули (8-10 секунд), могут быть допустимы накладные расходы. Если вы будете использовать внешние функции, не связанные с потоками, только в одном потоке за раз, вы можете быть в безопасности.

Проблема с использованием любой формы цикла событий заключается в том, что внешняя функция, которая не знает вашего цикла, никогда не вернет управление вашему циклу. Таким образом, вам больше нечего делать.

Что ж. В основном я видел 2 типа асинхронного API:

  1. Прерывать. Вы вызываете обратный вызов, который должен выполняться после вызова. GIO (часть ранее упомянутой GLib) работает таким образом. Его относительно легко программировать, но обычно у вас есть поток, в котором будет выполняться обратный вызов, измененный (кроме случаев, когда он интегрирован с основным циклом, как в случае GIO).
  2. Опрос. Вы проверяете, доступны ли данные. Так работают хорошо известные сокеты BSD. Его преимущество заключается в том, что он не обязательно интегрируется с основным циклом и выполняет обратный вызов в определенном потоке.

Если вы программируете для Gnome или Gtk +, я бы хотел добавить, что GTask кажется очень хорошим (потенциально хорошим? Я не использовал его). Вала будет лучше поддерживать асинхронные вызовы, подобные GIO.

Другие вопросы по теме