Exécution parallèle: blocage de réception, différé synchrone

Sep 29 2020

J'ai posé une question sur les erreurs survenues lors des appels de synchronisation parallèle et asynchrones. Et la réponse éclaire une question encore plus grande:

  • La construction de réception bloquante remplace-t-elle les appels .z.ps / .z.pg?
  • S'il existe un différé synchrone (utilisé dans mserve.q), existe-t-il quelque chose comme asynchrone différé ?

Mes observations basées sur la question précédente. Le cas 3 de cette question est correct:

q)neg[h]({neg[.z.w] x};42); h[]
42

Mais que se passe-t-il si nous voulons nous assurer que notre message a été envoyé:

q)neg[h]({neg[.z.w] x};42); neg[h][]; h[]
42

Ça semble ok, non? Si nous allons plus loin dans la documentation, nous découvrons qu'il existe un autre type d'assurance que nous avons: h""- message traité à distance, et dans ce cas nous avons une erreur:

q)neg[h]({neg[.z.w] x};42); neg[h][]; h""; h[]
'type
<hangs>

La proposition est donc la suivante - h[](envoyée dans la séquence appropriée) change en quelque sorte le comportement d'un expéditeur et peut être un processus récepteur pour le préparer à une telle communication.

Réponses

1 jasonfealy Sep 30 2020 at 03:27

Pour répondre à votre première question, je ne pense pas que "remplacer" soit le terme correct, mais plutôt le message entrant est attendu car il a été initié par le processus local, il n'est donc pas acheminé vers le gestionnaire .z.ps, contrairement aux messages dont le processus n'attendait pas, où .z.ps peut être utilisé pour s'assurer que le message n'est pas hostile ou quel que soit le cas.

Lorsque vous émettez une réception de blocage, l'indicateur O_NONBLOCK est effacé et recvfrom () bloque jusqu'à ce qu'un message arrive et l'indicateur O_NONBLOCK est remplacé

read(0, "h[]\n", 4080)                  = 4
fcntl(4, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(4, F_SETFL, O_RDONLY)             = 0
recvfrom(4,


"\1\0\0\0\25\0\0\0", 8, 0, NULL, NULL) = 8
recvfrom(4, "\n\0\7\0\0\0unblock", 13, 0, NULL, NULL) = 13
fcntl(4, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(4, F_SETFL, O_RDONLY|O_NONBLOCK)  = 0


Concernant votre deuxième question, je crois que le différé synchrone a été introduit dans kdb + v2.3 pour le scénario où un processus client ne devrait pas bloquer le processus distant pendant qu'il attend sa réponse. Le différé synchrone permet au serveur de traiter d'autres demandes client, tandis que le processus client se bloque jusqu'à ce que les informations demandées soient reçues. C'est bien lorsque le client ne peut rien faire d'autre tant qu'il n'a pas reçu la réponse.

Il y a des cas où aucun des processus ne devrait attendre l'autre - est-ce à cela que vous faites allusion? Si tel est le cas, un cas d'utilisation peut être quelque chose comme un système de passerelle à plusieurs niveaux, où une ou plusieurs passerelles envoient / reçoivent des messages entre elles, mais aucune ne se bloque ou n'attend. Cela se fait via des rappels asynchrones. Dans un système complexe avec plusieurs processus, chaque demande doit être étiquetée avec un identifiant pendant qu'elle est en vol afin de les suivre. De même, vous devez suivre quelle demande provient de quelle connexion afin de renvoyer les résultats au bon client.

Voici un exemple plus simple

////////////// PROC A //////////////
q)\p
1234i
q)remoteFunc:{system"sleep 4";neg[.z.w](`clientCallback;x+y)}

////////////// PROC B //////////////
q)h:hopen 1234
q)clientCallback:{0N!x;}; .z.ts:{-1"Processing continues..";}
q)
q)neg[h](`remoteFunc;45;55);system"t 1000"
q)Processing continues..
Processing continues..
Processing continues..
Processing continues..
Processing continues..
100

// process A sent back it's result when it was ready

Sur votre dernière question

  1. neg[h][]vide les messages asynchrones au moins aussi loin que tcp / ip. Cela ne signifie pas que la télécommande les a reçus. Le chaser h""vide tous les messages sortants sur h, envoie sa propre demande et traite tous les autres messages sur h, jusqu'à ce qu'il reçoive sa réponse.

  2. La poursuite des messages asynchrones est un moyen de s'assurer qu'ils ont été traités sur la télécommande avant de passer au message asynchrone suivant. Dans votre exemple, la poursuite suivie d'un appel suspendu n'est pas valide, pour une, elle entraînera une erreur et deuxièmement, ce n'est pas une tâche qui nécessite une garantie que le message asynchrone précédent a été entièrement traité avant de commencer.

Jason