2008-09-15 6 views
1

Lorsque j'essaie d'implémenter des appels d'API asynchrones/appels non bloquants, j'en connais un peu dans une application All Plain-C, j'ai lu un article sur APM (Asynchronous Programming Model) par Delegates. Fondamentalement, ce que je veux faire est d'appeler une API f1() pour faire une fonctionnalité (ce qui prend beaucoup de temps 8-10 secondes), donc j'appelle cette API f1(), oubliez-le, et continuez à faire un autre travail, par exemple. E/S pour récupérer les données pour l'appel suivant du f1() ou une fonctionnalité ne dépendant pas du résultat de f1(). Si quelqu'un a utilisé ce modèle de programmation APM, j'examine quelques explications concises pour implémenter des appels non bloquants.API asynchrones

Existe-t-il un autre moyen d'implémenter des API asynchrones, n'importe quelle autre bibliothèque/structure pouvant être utile dans ce cas?

Répondre

0

Remplacez les délégués par des pointeurs vers des fonctions en C, tout le reste est fondamentalement identique à ce que vous avez lu.

1

Vous devez créer une application multithread (ou multi-process). L'API f1() doit générer un thread (ou un processus) pour traiter les données dans un espace d'exécution séparé. À la fin, la routine f1() doit signaler au processus principal que l'exécution est terminée (signal(), files d'attente de messages, etc.).

1

Une méthode courante de programmation asynchrone dans un programme C simple consiste à utiliser une "boucle d'événements". Il existe de nombreuses bibliothèques que vous pourriez utiliser. Je suggère de jeter un oeil à glib.

Une autre alternative consiste à utiliser plusieurs threads préemptifs (un pour chaque opération simultanée) et de les synchroniser avec des mutex et des variables de condition. Cependant, le threading préemptif en C simple est quelque chose que j'éviterais, surtout si vous voulez écrire des programmes portables. Il est difficile de savoir quelles fonctions de la bibliothèque sont réentrantes, la gestion des signaux dans les programmes threadés est un problème et, en général, les bibliothèques C et les fonctions système ont été conçues pour un usage monothread.

Si vous envisagez d'exécuter votre application uniquement sur une plate-forme (comme Windows) et que le travail effectué avec f1() est relativement simple, le thread peut être OK.

1

Si la fonction f1() à laquelle vous faites référence n'est pas implémentée elle-même de façon asynchrone, vous devrez l'emballer vous-même dans son propre thread. Lorsque vous faites cela, vous devez être prudent en ce qui concerne les effets secondaires qui peuvent être causés par cette fonction particulière appelée. De nombreuses bibliothèques ne sont pas conçues de manière thread-safe et plusieurs appels simultanés de fonctions à partir de telles bibliothèques conduiront à la corruption de données. Dans ce cas, vous devrez peut-être terminer la fonctionnalité dans un processus de travail externe. Pour le levage lourd que vous mentionnez (8-10 secondes) que les frais généraux peuvent être acceptables. Si vous n'utilisez que les fonctions externes non threadsafe dans un thread à la fois, vous pouvez être en sécurité. Le problème avec l'utilisation de n'importe quelle forme de boucle d'événements est qu'une fonction externe qui ne connaît pas votre boucle ne ramènera jamais le contrôle à votre boucle. Ainsi, vous n'obtiendrez rien d'autre.

0

Bien. Fondamentalement, j'ai vu 2 types d'API asynchrone:

  1. Interruption. Vous appelez un rappel qui doit être effectué après l'appel. GIO (partie de GLib précédemment mentionné) fonctionne d'une telle manière. Il est relativement facile de programmer avec mais vous avez habituellement le fil dans lequel le rappel sera exécuté changé (sauf si elle est intégrée à la boucle principale comme dans le cas de GIO).
  2. Sondage.Vous vérifiez si les données sont disponibles. Les célèbres BSD Sockets fonctionnent de cette manière. Il a l'avantage de ne pas être nécessairement intégré à la boucle principale et d'exécuter le rappel dans un thread spécifique.

Si vous programmez pour Gnome ou Gtk + J'aimerais à base d'ajouter que GTask semble être une très belle (potentiellement agréable? Je ne l'ai pas utilisé). Vala aura un meilleur support pour les appels asynchrones de type GIO.