Я собираюсь разработать C api для некоторой функциональности, и я хотел бы сделать его асинхронным, поскольку раскрытая функциональность может занять некоторое время. Использование блокирующего API, вероятно, не очень хорошая идея, так как пользователю API необходимо совершать много одновременных вызовов.
Как правильно спроектировать интерфейс, чтобы я мог уведомить пользователя о завершении асинхронной операции?
Я могу придумать несколько разных подходов, но не могу сказать, что мне известны лучшие практики для этого. У кого-нибудь есть опыт работы с подобным API: s?
В этом примере мы хотим вернуть int, содержащий ответ.
Функция обратного вызова:
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 */