Я собираюсь разработать C API для некоторых функций, и я хотел бы сделать его асинхронным, поскольку открытые функции могут занять некоторое время. Использование блокирующего API, вероятно, не является хорошей идеей, поскольку пользователю API нужно будет совершать много одновременных вызовов.
Как правильно спроектировать интерфейс, чтобы я мог уведомить пользователя о завершении асинхронной операции?
Я могу придумать несколько разных подходов, но не могу сказать, что знаю лучшие практики для этого. Есть ли у кого-нибудь опыт работы с подобными API?
В этом примере цель состоит в том, чтобы вернуть целое число, содержащее ответ.
Функция обратного вызова:
typedef void (*callback_function)(int, void *);
/* Calls the callback function with the answer and cookie when done */
error_code DoSomething(callback_function, void *cookie);
Опрос:
error_code DoSomething(void *cookie);
/* Blocks until any call has completed, then returns the answer and cookie */
error_code WaitForSomething(int *answer, void **cookie);
Очередь событий для конкретной платформы
/* Windows version, the api calls PostQueuedCompletionStatus when done */
error_code DoSomething( HANDLE hIoCompletionPort,
ULONG_PTR dwCompletionKey,
LPOVERLAPPED lpOverlapped );
Пользователи этого API, как правило, управляются событиями, поэтому проекты, подобные приведенному ниже, вероятно, не будут хорошей идеей.
Фьючерсы:
/* External dummy definition for a future */
struct Future_Impl {
int unused;
};
typedef Future_Impl *Future;
/* Initializes a future, so that it can be waited on later */
error_code DoSomething(Future *future);
/* Blocks until the result is available */
error_code WaitForSomething(Future future, int *answer);
Фьючерсы/события для конкретной платформы:
/* Windows version, the api signals the event when done */
error_code DoSomething( HANDLE hEvent, int *answer );
/* Can be waited on using WaitForMultipleObjects,
but that has a limit on how many events that can be used */