Éviter la récursivité lors de la lecture / écriture d'un port de manière synchrone?

108

Toutes les opérations de port dans Rebol 3 sont asynchrones. La seule façon que je peux trouver pour faire une communication synchrone est d'appeler wait.

Mais le problème avec l'appel wait dans ce cas est qu'il vérifiera les événements pour tous les ports ouverts (même s'ils ne sont pas dans le bloc de port passé à wait). Ensuite, ils appellent leurs gestionnaires d'événements qui répondent, mais une lecture / écriture peut être effectuée dans l'un de ces gestionnaires d'événements. Cela pourrait entraîner des appels récursifs à "wait".

Comment puis-je contourner cela?

Shixin Zeng
la source
8
En fait, je ne pense pas qu'il y ait de solution à cela dans l'implémentation actuelle de R3, alors j'ai ajouté un raffinement "/ only" à "wait", avec lequel, il n'attendra que les ports fournis pour "wait" , et ainsi éviter les appels récursifs. Voir ma demande de tirage sur: github.com/rebol/rebol/pull/177
Shixin Zeng
1
Par curiosité, pourquoi en avez-vous besoin pour être synchrone?
toadzky
1
Il existe de nombreuses situations dans lesquelles le codage avec un port synchrone est beaucoup plus simple: supposons que vous souhaitiez envoyer un e-mail en cliquant sur un bouton et signaler s'il réussit ou échoue. Il est beaucoup plus facile d'attendre la fin avant de faire autre chose.
Shixin Zeng
1
devez-vous absolument utiliser Rebol?
Rivenfall
1
Oui. Il s'agit en fait plus d'une question sur Rebol 3 que de communication synchrone en général.
Shixin Zeng

Réponses:

1

Pourquoi ne créez-vous pas une sorte de fonction "Buffer" pour recevoir tous les messages d'entrées assynchrones et les traiter comme FIFO (premier entré, premier sorti)?

De cette façon, vous pouvez conserver les caractéristiques Assync de vos ports et les traiter en mode synchro.

David BS
la source
0

dans les cas où il n'y a que des événements asynchrones et que nous avons besoin d'une réponse synchrone, démarrez un minuteur ou une mise en veille pour le délai d'expiration, si le gestionnaire ou l'objectif requis est atteint, dites vrai, sinon faux et assurez-vous que l'événement est annulé / réinitialisé pour le même si critique.

mkumar
la source
0

Je pense qu'il y a 2 problèmes de conception (peut-être intrinsèques aux outils / solutions à portée de main).

  1. Waitfait trop - it will check events for all open ports. Dans un environnement sain, l'attente ne doit être mise en œuvre que là où c'est nécessaire: par appareil, par port, par socket ... La création d'interdépendances inutiles entre les ressources partagées ne peut pas bien se terminer - surtout en sachant que les ressources partagées (même sans interdépendances) peut créer beaucoup de problèmes.

  2. Les gestionnaires d'événements peuvent en faire trop. Un gestionnaire d'événements doit être aussi court que possible et il ne doit gérer que l'événement. Si c'est fait plus, alors le gestionnaire en fait trop, surtout s'il implique d'autres ressources partagées. Dans de nombreuses situations, le gestionnaire enregistre simplement les données qui seront perdues autrement; et un travail asynchrone fera les choses les plus complexes.

virolino
la source
-1

Vous pouvez simplement utiliser un verrou. Cummunication1 peut définir un état de verrouillage global, c'est-à-dire avec une variable (assurez-vous qu'il est thread-safe). locked = true. Ensuite, Communication2 peut attendre qu'il soit déverrouillé.

loop do
    sleep 10ms
    break if not locked
end
locked = true
handle_communication()
Rivenfall
la source
1
Il s'agit en fait plus d'une question sur Rebol 3 que de communication synchrone en général.
Shixin Zeng