Page 1 sur 1

[ TUTO ] Partage de variable par accès direct en RAM

Posté : ven. 25 avr. 2008 22:46
par sylvanie
Souvent pour échanger des infos entre 2 scripts, on passe par des écriture de
fichiers. Or dans beaucoup de langages on passe par des partages de zone en RAM
afin d'aller plus vite et ne pas laisser de trace sur disque (je pense plus
à la rémanence qu'à l'oublie d'effacement...)

En Autoit c'est aussi possible grâce à la librairie "memory.au3" dont je joint une copie en bas de ce post.

deux scripts sont présentés : un partageur et un utilisateur (appelé client)

le partageur va appeler le client en lui donnant son PID et un pointeur (adresse)
vers une variable typée.

Ainsi le client pourra utiliser la variable et celle-ci sera également
utilisable en temps réelle par l'appelant

en gros
partageur déclare i=6 et lance client avec son pid et l'adresse de i
si client fait i=i+i, alors i vaut aussi 7 dans l'appelant.

Du coups nous avons un process principal (partageur) qui peut traîter le prog
prncipal et un auxilière (client) qui update des valeurs du principale dans
un thread diférent, donc on n a plus de problème de type un while 1 appelant
un autre while 1 qui bloque le premier ... certeon peut passer par de l'échange par fichier mais les temps d'accès lecture / écriture vont être bien plus lents et dangeureux

pour tester ceci, compiler le client.au3 en client.exe dans le même
rep que createur.au3 (le partageur)
Puis lancez avec scite (pour lire les consolewrite ...) createur.au3

Créateur.au3 :

Code : Tout sélectionner

; partie "partageuse" qui va appeler un exe en lui donnant son PID et un pointeur pour partager une info en RAM

$my_str=DllStructCreate("int partage") ; création d'une structure qui contiendra un int à partager

DllStructSetData($my_str,"partage",35) ; initialistaion à 35, comme ça ....

$ptr=DllStructGetPtr($my_str,"partage") ; on récupère l'adresse de la structure (pointeur)

ConsoleWrite($ptr&@CRLF) ; ça c'est du debug pour voir si on a bien un pointeur non NULL, c'est tpujours bon pour un poc

ConsoleWrite(@AutoItPID&@CRLF) ; idem pour le PID

Run("client.exe "&@AutoItPID&" "&$ptr) ; on lance le deuxième script compilé sous le nom de client.exe avec comme argument le PID de l'appelant (ce script) est le l'adresse de la variable à partager
$old=DllStructGetData($my_str,"partage") ; on récupère la valeur de l'integer donc 35 (pour l'insant)
;boucle d'attente d'évènement
While 1
    Sleep(250)
    $encours=DllStructGetData($my_str,"partage") ; on récupère la valeur actuelle, qui n'est pas modifié ici par ce script
    If $old <> $encours Then ; ha ha ! modification par le client!
        $old=$encours
        ConsoleWrite($encours&@CRLF)
    EndIf
WEnd

;Run("client")
Client.au3 :

Code : Tout sélectionner

; le "client" qui est appelé via le "partageur" qui lui donne son PID et l'adresse de la valeur  mise à dispo

#include "memory.au3" ; librairie de gestion de memoire en RAM

$cpt=0

If $CmdLine[0]<>2 Then Exit 1 ; on attends 2 arg : PID + adresse (pointeur)

$pid=$CmdLine[1] 
$adress=$CmdLine[2] 

;boucle d'update qui va faire +1 toute les 2 secondes
While 1
    
    $cpt+=1
    updatememory($pid,$adress,$cpt)
    Sleep(2000)
    
WEnd


Func updatememory($process_id,$adress_mem,$val)
    ;Local $offset=0
    Local $DllHandle = _MemoryOpen($process_id); on ouvre la partie de mémoire utilisée par le pid de l'appelant
    Local $Data = _MemoryWrite($adress_mem, $DllHandle,$cpt,"int"); on écrit à l'adresse passer en arg la valeur typée en int (type original de la valeures dont l'adresse a été passée)
    _MemoryClose($DllHandle) ;on referme le handle ouvert sur cette zone
EndFunc
 
Conclusion :
point positif : c'est plus rapide et pas de rémanence comme avec les stockage sur support magnétique (sauf ram magnétiques mais ça court pas les rues)
point négatif : les accès concurentiels... et oui car mêm si on n'a pas les lourdeurs du fileopen, write et close, la problèmatique reste la même : que se passe t il si un process (voir plusieurs, c'est le pire cas ) écrit au moment où l'autre lit, que se passe t il ? des bugs de valeurs, voir plantage (mais ceci reste vrai pour tout type de partage).
Quant on n'a que deux petites applis popote maison , ça va, on peut négliger cette aspect, mais si on parle d'appli attaquée par plusierus clients, alors faut passer à la prise de jeton d'accès : l'art de la sémaphorisation, mais ceci sera un autre tuto :roll:

Edit Tlem : Vous trouverez dans le lien qui suit, une autre solution pour le transfert de donnée(s). Cette méthode, prend en compte les variables de tous types (y compris les tableaux), ainsi que des objets COM.
http://www.autoitscript.com/forum/topic ... _p__880884

.

Re: [ TUTO ] partage de variable par accès direct en RAM

Posté : sam. 26 avr. 2008 00:39
par Tlem
Je me suis permis de modifier le post pour plusieurs raisons.

1 - Le fichier Memory.au3 existe déjà dans les includes de AutoIt, mais ne contient pas les même fonctions ... J'ai donc renommer celui-ci Memory2.au3

2 - Je l'ai placé en fichier joint, pour tout simplement faire des économies de place sur la base de donnée.
Il faut savoir que l'adjonction de la coloration syntaxique augmente de manière significative la quantité de place utilisée pour quelques lignes de code puisque le code est mémorisé avec les TAGs html tout comme le faisait Forum Color !!!
Pour donner un exemple, les commandes sont mémorisée avec la couleur + le lien de l'aide ce qui fini par faire pas mal de données pour un simple mot. :(

Re: [ TUTO ] partage de variable par accès direct en RAM

Posté : sam. 26 avr. 2008 01:10
par sylvanie
Merci, je n'avai pas vu que le parcourrir éttait en bas ... je le cherchais en haut ...

Par contre pour le memory.au3, heureusement que tu l'as vu, car je n'avais pas fait attention qu'il avait été intégré. Le plus ennuteux est qu'effectivement les prototypes sont différents. Il faudra que je regarde les équivalents. En tout cas ce tuto reste vrai avec cette ancienne version beta, mais il faudra regarder la portabilité avec la release officielle...

Re: [ TUTO ] partage de variable par accès direct en RAM

Posté : sam. 26 avr. 2008 18:47
par sylvanie
Je viens de recherché l'udf (celle que j'utilise et non le .au3 standard), et il semble qu'il ai changé de nom depuis que j'avais vu : NomadMemory.au3 et non Memory.au3

Re: [ TUTO ] Partage de variable par accès direct en RAM

Posté : jeu. 27 août 2009 22:33
par timmalos
Vu que j'utilise souvent cette méthode je profite pour dire encore Merci

et à quand le tuto sur : l'art de la sémaphorisation ? :P

Tu connais un lien sympa pour apprendre ca?

Re: [ TUTO ] Partage de variable par accès direct en RAM

Posté : jeu. 27 août 2009 23:12
par Voodoo
Pas grand chose à savoir sur les sémaphores. Regarde ici. Le problème c'est de bien les placer dans ton algorithme.

Sinon pour la communication inter process vous pouvez toujours utiliser la couche Tcp/Udp. :D (Au lieu de bidouiller la mémoire d'un process :P )

Re: [ TUTO ] Partage de variable par accès direct en RAM

Posté : ven. 28 août 2009 13:45
par timmalos
J'ai pas trop compris le principe.

On fait une fois +1 une fois -1 pour s'assurer de toujorus rester avec le même nombre et ainsi on peut savoir quel programme doit intervenir sur la variable en premier?

Re: [ TUTO ] Partage de variable par accès direct en RAM

Posté : ven. 28 août 2009 15:45
par Voodoo
En deux mots: Le but est d'éviter les accès concurrentielles. Pour cela on modélise le principe de sémaphorisation avec trois opération:
  • init(S,int): initialisation de notre sémaphore S
  • P(S) opération de demande (S-1)
  • V(S) opération de libération (S+1)
Imagine que nous sommes dans un débat. Il y a 5 participants. Parler en même temps ne rime à rien, on met donc en place un système de jeton qui établira qu'une seule personne peut parler à la fois (init(S,1)). Celui qui a le jeton peut parler. Notre jeton c'est S. Le premier participant fait un P, il obtient ainsi la parole, notre S est donc à zéro. Pendant qu'il parle, le participant 2 demande le jeton. Donc P à nouveau. Opération non accepté car S est à zéro, le participant est donc mis en attente. Il faut attendre que le participant 1 libère le jeton (V) pour pouvoir l'obtenir (toutes les demandes seront mis en attente).

Un sémaphore initialisé à 1 comme l'exemple porte un nom: c'est un mutex.

Bien sur on initialise le sémaphore avec la valeur qui nous convient. Imaginons que 2 participants puissent parler en même temps. On se comprend encore. 1000 participants sa devient plus dur...

Re: [ TUTO ] Partage de variable par accès direct en RAM

Posté : ven. 28 août 2009 19:55
par timmalos
Merci de l'explication.

Re: [ TUTO ] Partage de variable par accès direct en RAM

Posté : mar. 06 mars 2012 23:56
par Tlem
Pour des besoins professionnel, j'ai eu l'occasion de faire des recherches sur la communication adoptée par des logiciels utilisés dans le cadre de mon activité. Ce qui m’amène à faire un gros déterrage du sujet, pour rajouter un complément qui pourrait être utile à d'autres en ce qui concerne l'échange de données entre scripts.

Ci-dessus à été décrit une manière de partager une donnée par accès direct à un espace mémoire. Il existe aussi pour ce type d'application ce que l'on appel le DDE (Dynamic Data Exchange) ou encore en Français : "Échange dynamique de données". On constatera qu'il est aussi fait état de OLE et COM. :mrgreen:

Pour plus d'informations, je vous invite à cliquer sur les liens ci-dessus et pour un exemple d'utilisation avec AutoIt de consulter ce sujet : DDEML.au3 - DDE Client + Server

Amusez vous bien. ^^