Question

J'ai un serveur de discussion en C / Linux à l'aide de sockets TCP.Lorsque vous utilisez Libev, je suis capable de créer un observateur EV_IO pour lire des événements une fois pour une prise.Quelque chose comme:

ev_io* new_watcher = (ev_io*)malloc(sizeof(ev_io));

//initialize the watcher
ev_init(new_watcher, read_cb);

//set the fd and event to fire on write
ev_io_set(new_watcher, watcher->fd, EV_READ);

//start watching
ev_io_start(loop, new_watcher);

Et cela fonctionne bien parce que l'événement de lecture ne tirera que lorsqu'il y a des données à lire.Cependant, je dois traiter des événements écrits différemment car ils tirent constamment, même lorsque je n'ai pas de données à écrire.Pour résoudre ce problème, j'ai ma lecture_Callback Créer un observateur EV_IO pour obtenir des données d'écriture uniquement lorsqu'il existe des données prêtes à être écrites, puis le write_callback supprimera l'observateur une fois qu'il a envoyé son message.

Cela signifie que je fais une allocation, une initialisation, un réglage, une surveillance, une négociation et une interlocation de l'observateur de l'écriture à chaque fois que je dois gérer un message.Je crains que je puisse être manipulé cela de manière incorrecte et inefficace.

Quelle est la meilleure méthode pour manipuler des événements Write_Callback à Libev?

Merci d'avance.

Était-ce utile?

La solution

L'allocation peut ajouter des frais généraux, vous pouvez utiliser une variable statique à la place de MALLOC, ou MALLOC une fois et que librement, après la fin de la boucle d'événement. Il vous suffit de définir avant d'écrire et de non défini après que cela réussit.Mais oui, c'est comme ça que cela doit être fait.

Autres conseils

facile, il y a aussi ev_io_stop, donc ce que vous faites n'est pas démarrer l'observateur d'écriture, à moins que vous n'ayez rien à écrire, et à l'intérieur du rappel, vous appelez ev_io_stop lorsque vous avez écrit le tampon entier.

Dans le cas commun où vous débordez rarement TRHE Ecrire un tampon (car vos données sont petites et que vous ne savez pas trop souvent), vous pouvez rendre cela plus efficace en essayant d'écrire directement les données (si l'observateur n'est pas actif.) et tamponner uniquement les données et démarrer l'observateur d'écriture si vous ne pouviez pas le plus frapper complètement.

Sous les hypothèses ci-dessus, cela signifie que vous n'avez presque jamais besoin de démarrer l'observateur d'écriture.L'inconvénient est un code beaucoup plus complexe, donc dans de nombreux cas, il est préférable de commencer par SI SIMPLE "Ajoutez des données pour écrire tampon, démarrer l'observateur, à l'intérieur de l'observateur, arrêtez-le si la mémoire tampon a été écrite entièrement" logique.

La façon dont j'ai résolu cette situation était d'avoir une fonction pour écrire des données qui prend un pointeur sur le tampon et la longueur. Il stocke le pointeur et la longueur dans une structure de données de la file d'attente et active l'événement d'écriture.

Lorsque le rappel d'événement d'écriture déclenche, il vérifie la file d'attente d'écriture pour voir s'il y a des écrit en attente. S'il y en a une, il prend la prochaine inscription en attente dans la file d'attente et l'écrit au descripteur de fichier. Ensuite, juste avant la sortie de l'écriture de rappel, il vérifie si la file d'attente en attente est vide. Si tel est le cas, il désactive l'événement d'écriture.

Si vous effectuez vos objets de lecture / écriture d'événement Global Variables, ils ne seront que alloués et libérés une fois. Vous activez l'événement d'écriture chaque fois que vous savez qu'il y a des données à écrire et que vous le désactivez une fois qu'il n'y a plus de données à écrire.

Mon code est un peu plus compliqué que la description ci-dessus, mais je posterai un lien ici simplement pour que vous puissiez jeter un oeil. Le code dont je parle spécifiquement est dans l'AIOFD.HI et AIOFD.C (AIOFD== Synchrones d'E / S Asynchrone File): https://bitbucket.org/wookie/cuttil/

J'espère que cela vous aidera.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top