2008-09-15 4 views
1

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

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

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

ответ

0

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

1

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

1

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

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

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

1

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

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

0

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

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

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

Смежные вопросы