6
votes

La bibliothèque Hiredis Redis crée-t-elle son propre thread pour les rappels ASYNC?

J'utilise REDIS dans un environnement multithreadé et pose une question sur la manière dont elle fonctionne. J'utilise la bibliothèque Hiredis C dans mon application C ++.

Ma question est la suivante: Si j'utilise le mode asynchrone lorsqu'un rappel est tiré, le rappel sera-t-il traité dans un autre fil créé par le client Redis? Comme dans ce sera le fil où l'appel a été créé ne pas être affecté par la manipulation du rappel? Merci!


0 commentaires

3 Réponses :


1
votes

Redis Client ne crée pas de fils de claven supplémentaires et fonctionne dans le thread existant.

Les REDIS ont travaillé dans un autre processus (principal). L'API Redis que vous utilisez travaillé dans votre processus local et utilisez la communication interprocessée au processus principal. La demande ASYNC signifie que votre processus ou votre thread mettez la tâche à un autre et, après cela, peut faire toute autre tâche YTT ou d'attente. Un peu plus tard, une réponse ASYNC est arrivée à votre demande et disponible pour une utilisation. Votre application doit utiliser https://fr.wikipedia.org/wiki/event_loop ou toute gestion ASYNC Système qui vous avertit en appelant Callback pour gérer l'événement (dans ce cas, Redis Réponse).

L'architecture asyncréancière signifie que vous courez une boucle d'événement qui appelle des gestionnaires de rappel pour chaque événement. Lorsque le rappel appelé, vous pouvez créer un nombre de tâches asynchrones. Une fois la tâche créée, elle supposait que lorsque la tâche effectuée ou une erreur se produise, le gestionnaire d'événements de rappel sera appelé. Le rappel peut être affecté à l'application Démarrer ou à une nouvelle connexion Web apparaît. Lorsque le rappel appelé Vous pouvez créer la tâche REDIS et le rappel d'événement de résultat ultérieur sera appelé. Toutes choses dans le fil actuel. I НOU Avez-vous un fil multiple, raisonnable de vous attendre à avoir une boucle d'événement par chaque fil.

Nature filetée unique de Redis: http://redis.io/ Thèmes / Latence # Single-Fileté-Nature-of-Redis

Le socket client est mis en état non bloquant depuis que ReDIS utilise le multiplexage et les E / S non bloquantes. http://redis.io/topics/cliients Cela signifie que votre client ne sera jamais bloqué.

de Redis 2.4 threads à Redis utilisé uniquement pour effectuer des opérations d'E / S lentes en arrière-plan, principalement liées aux E / S du disque, mais cela ne change pas le fait que ReDIS sert toutes les demandes à l'aide d'un seul fil. .


9 commentaires

Je comprends comment fonctionnent les bibliothèques d'événements de style libuv. Ce n'est pas ma question. Ma question concerne la dynamique de travail interne de la bibliothèque client de Redis et où les rappels sont traités. Il doit y avoir un autre fil impliqué car sinon, il serait bloqué, à moins que les opérations de DB ne soient arrivées que lorsque le thread bloque pour une certaine raison. Auquel cas un moment (vrai) {} causerait que les opérations ASYNC ne se produisent jamais. Ma question est à quel fil gère le rappel.


Serveur (Main) Threan Servez la tâche et envoyez une réponse à votre fil. Votre fil n'est pas bloqué carté de chaussette non bloquée utilisée pour le transport. Lorsque le transport de la prise est effectué, vous pouvez faire des données sur ce dont vous avez besoin dans votre fil. Quelle raison vous voulez dire pour bloquer votre fil?


Même si une prise non bloquante est utilisée, l'état de la prise doit être vérifié par un fil. Si le thread principal fait un calcul, il ne peut pas gérer la prise, même si la prise est non bloquée. De plus, la bibliothèque ne vous oblige pas à appeler une fonction pour lui donner le contrôle de l'expédition pour un thread comme Libuv (une bibliothèque d'événements). Il doit y avoir un autre fil impliqué dans cela quelque part.


Ne pas arroser à ce sujet. Ceci est la tâche du système d'exploitation. Ceci est différent et de la mise en œuvre dépendamment. Pour plus d'informations, reportez-vous à: en.wikipedia.org/wiki/asynchronous_i/o EN.Wikipedia.org/wiki/epoll en.wikipedia.org/wiki/kqueue


J'ai écrit un serveur Epoll et comprendre comment ça fonctionne. Epoll produit une liste d'événements. Cette liste d'événements doit être vérifiée pour savoir que les données sont arrivées. Parce que cette vérification n'est pas effectuée par le thread principal (aucune fonction n'est appelée pour l'initier à la manière dont Libuv)) puis un autre fil doit faire la vérification. Il n'y a pas d'autre moyen. Epoll nécessite toujours un thread de vérifier constamment. Cela signifie simplement que l'OS génère des événements au lieu de 1000 threads chacun en vérifiant une prise.


Lorsque vous avez une tâche pour calculer le faire. Lorsque le calcul est effectué, renvoyez du rappel à la boucle d'événement appelant la vérification de l'époll. Vos Redis Socked sont-ils ajoutés dans la même liste d'époll? Si vous ne pouvez pas intégrer toutes les prises à une seule époll que vous avez besoin d'un autre processus ou un autre thread de travailler avec elle. Mais besoin de comprendre la raison pour laquelle vous ne pouvez pas utiliser un seul fil avec une époll. Par exemple, Hiredis fonctionne facilement avec n'importe quelle bibliothèque d'événements: Github.com/redis/heiredis#asynchronous-api < / a>


Vérifiez s'il vous plaît en attente disponible pour modifier la balise de base de données vers une balise de question asynchrone?


@ Erick2Red, vous dites des choses étranges. Lisez la première chaîne de réponse et première chaîne d'hiretis Readme. L'hiredis est un client minimaliste de Redis Server. Hiredis est juste Redis API via IPC et fonctionne avec toute bibliothèque d'événements . Vous pouvez effectuer une recherche via des sources d'hirette pour tout fonctionnement de fil de création si le doute. Faites toutes les choses liées à RedisasyncContext dans un fil si vous utilisez Multhreading. Un RedisasyncContext n'est pas le fil-faire. Faire plusieurs connexions un par thread si vous voulez utiliser des Reids dans différents fils


@oklas. Je m'excuse, tu as raison. Je manque de lire la réponse hier. Ce que je pense que cela a besoin maintenant, c'est un peu de style.



0
votes

Hiredis appelle le rappel lorsque vous appelez RedisasynchandLeread (). Par conséquent, les rappels sont appelés quel que soit le fil que vous avez utilisé pour appeler RedisasynChandleread ().

Je pense qu'un exemple de Redis Async minimal, dans Linux-ish C, ressemblerait à ceci (vérification des erreurs supprimées pour la clarté): < Pré> xxx


0 commentaires

0
votes

RedisasynChandlerlead () ou RedisasynChandlewrite () invoquera tous les rappels que vous avez enregistrés précédemment. Il ne "tire" pas par voir. Ni la documentation ni le fichier async.h ne permettent que vous obtenez sur le descripteur de fichier (AC-> C.FD) à mettre en œuvre, dites, une boucle d'événement Epoll:

  #define MAX_EVENTS 10

  int epfd;
  if((epfd = epoll_create1(0)) == -1) {
     // handle error
  };

  redisAsyncContext *ac = redisAsyncConnect("127.0.0.1", 6379);

  if(epoll_ctl(epfd, EPOLL_CTL_ADD, ac->c.fd, &(struct epoll_event) { .events = EPOLLIN | EPOLLOUT | EPOLLET }) == -1) {
     // handle error
  }

  int nfds;
  struct epoll_event events[MAX_EVENTS];
  for(;;) {
     if((nfds = epoll_wait(epfd, events, MAX_EVENTS, -1) == -1) {
       // handle error
     }
     for(int i = 0; i < nfds; i++) {
         if(events[i].events & EPOLLIN) redisAsyncHandleRead(ac);
         if(events[i].events & EPOLLOUT) redisAsyncHandleWrite(ac);
     }
  }


0 commentaires