eine ressource in 2 dlls synchronisieren

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • eine ressource in 2 dlls synchronisieren

    hi,

    ich habe eine kleine frage zwecks benutzung gleicher ressourcen in 2 dlls. (eine c und die andere native c++ - VS8)
    die zweite dll füllt ein byte-array und die zweite soll daraus auslesen. beide sind in einem prozess. schwanke noch zwischen shared memory und einem funktionsaufruf von der ersten zur zweiten dll.

    in beiden fällen benötige ich jedoch eine synchronisierung.
    habe was über kritische abschnitte und mutexen gelesen. jedoch habe ich das so verstanden, dass die synchronisierung in einem code und 2 threads sein muss und net wie bei mir in 2 verschiedenen codes von 2 verschiedenen threads (dlls). kann man dies trotzdem sauber lösen?

    danke schonmal
    Gruß
    Steff
    ___

    Der Optimist sieht in jedem Problem eine Aufgabe.
    Der Pessimist sieht in jeder Aufgabe ein Problem.

    http://autoexport.sunbird-kalender.de
  • Kritische Abschnitte werden mit einem Mutex oder einer Semaphore gesichert, damit nicht ein anderer Prozess ebefnalls in den kritischen Abschnitt eintritt und die selbe Resource verwendet. Klingt kompliziert, bezeichnet aber eigentlich ein globale Variable die alle ändern können. Das kannst du selber lösen oder die Api verwenden WinAPI kennt Funktionen für Semaphoren und Mutex, die sind im gegensatz zu einer globalen Variable im System global Abrufbar.

    Es gibt aber auch noch andere Möglichkeiten in Windows, die zwar hauptsächlich für Interprozesskommunikation gedacht sind, aber manchmal auch bei nur einem Prozess ganz gut funktionieren (Mapped File, Named Pipe,...).
    ~ mfg SeBa

    Ich beantworte keine PMs zu Computer-/Programmierproblemen. Bitte wendet euch an das entsprechende Forum.

    [Blockierte Grafik: http://i.creativecommons.org/l/by-sa/3.0/80x15.png]
  • danke erstmal für die antworten .....

    SeBa schrieb:

    Es gibt aber auch noch andere Möglichkeiten in Windows, die zwar hauptsächlich für Interprozesskommunikation gedacht sind, aber manchmal auch bei nur einem Prozess ganz gut funktionieren (Mapped File, Named Pipe,...).

    gerade habe ich eine Named Pipe implementiert. jedoch sind die dlls ziemlich performance-lastig und deswegen wollte ich die pipe drausen haben.
    kennst du dich mit named pipes aus? der wird doch außerhalb vom prozess erstellt, oder? dass sind ja dann immer prozesswechsel? oder meinst du, dass die named pipe ausreicht und es net schneller geht? also mir geht es hauptsächlich um performance und prozessorlast.

    "phax" schrieb:

    Du kannst die Kopplung auch dynamisch mit LoadLibrary und GetProcAddress machen. Damit brauchst du keine Verbindung beim Linken, sondern erst zur Laufzeit.

    ... das habe ich net ganz verstanden. also ich linke sie auch dynamisch mit loadlibrary. aber damit lade ich ja nur den funktionsaufruf, oder? also praktisch meine 2. wahl üder den funktionsaufruf. oder was meinst du?
    Gruß
    Steff
    ___

    Der Optimist sieht in jedem Problem eine Aufgabe.
    Der Pessimist sieht in jeder Aufgabe ein Problem.

    http://autoexport.sunbird-kalender.de
  • Wenn du zwei DLLs zusammen linkst hast du in der einen DLL einen hardcodierten Verweis auf die andere DLL (in der Import-Table).
    Wenn du Variante LoadLibray/GetProcAddress verwendest gibt es keinen hardcodierten Eintrag in der Import-Table und du kannst selber zwischen den Fällen unterschieden falls die andere DLL da ist und wenn nicht.
    -> Das entspricht der Variante mit Funktion der anderen DLL aufrufen
  • Ja, die wird außerhalb des Prozesses angelegt. Am performantesten wäre wenn du dir eine eigene Statusvariable bastelst mit der du Zugriffe sperren und wieder freigeben kannst. Du musst zusehen, dass wenn du, wenns gesperrt ist, in dem Thread der nicht zugreifen kann etwas anderes Produktives machen kannst, denn warten ist Verschwendung von Betriebsmitteln.
    ~ mfg SeBa

    Ich beantworte keine PMs zu Computer-/Programmierproblemen. Bitte wendet euch an das entsprechende Forum.

    [Blockierte Grafik: http://i.creativecommons.org/l/by-sa/3.0/80x15.png]
  • Eine Statusvariable ist nicht wirklich sicher, da das setzen einer Variable mehr wie einen Prozessorbefehl erfordert:
    Laden aus dem RAM -> ändern -> speichern in den RAM

    mov eax lock ;Lock in den register lesen
    cmp eax 1 ;Locked?
    je no_acess ;Kein Zugriff
    mov lock 1 ;Lock setzen
    jmp ciritical_section ;Sicherer Zugriff scheinbar möglich

    oder so ähnlich.
    Dabei kannst du auch ungünstig preemptet werden
  • Es gibt noch mehr Probleme, denn wenn die Prozesse nicht vollkommen unabhängig voneinander sind, dann muss er zusehen, dass er Deadlocks ausschließen kann (Philosophenproblem).
    ~ mfg SeBa

    Ich beantworte keine PMs zu Computer-/Programmierproblemen. Bitte wendet euch an das entsprechende Forum.

    [Blockierte Grafik: http://i.creativecommons.org/l/by-sa/3.0/80x15.png]
  • also ich habe nun folgendes gemacht...

    ich linke dynamisch die 2. dll zur ersten (was ich eh schon gemacht habe). in der 2. fülle ich das byte-array schütze dies über eine CRITICAL_SECTION. desweiteren habe ich eine funktion erstellt. die funktion bekommt als parameter einen LPCRITICAL_SECTION und einen byte zeiger, die ich dann auf die lokalen referenziere.
    somit rufe ich von der 1. (wo ich das array auslesen) per getprocadress die funktion auf und referenziere die lokalen zeiger, so dass ich den gleichen CRITICAL_SECTION und byte-array benutzen kann.

    was meint ihr dazu? ist das eine lösung? also ich meine eine ziemlich dreckige .. jedoch ist mir keine andere eingefallen.

    des komische ist, dass es im debug-build geht und im release net :(
    Gruß
    Steff
    ___

    Der Optimist sieht in jedem Problem eine Aufgabe.
    Der Pessimist sieht in jeder Aufgabe ein Problem.

    http://autoexport.sunbird-kalender.de
  • Dlls haben nichts (oder wenig) mit threads zu tun ...

    In deiner einleitung schreibst du auch nix ueber multithreading .... verwendest du das denn auch expliziet ?
    Wenn nein, sind deine Locks (CRITICAL_SECTIONS) eigentlich ueberfluessig, ok, vielleicht fuer spaetere mt verwendung vorgesehen.
    in beiden fällen benötige ich jedoch eine synchronisierung.

    Ohne Multithreading brauchst du definitiv keine Synchronisierung

    bei Multithreading kannst du auf den Speicher einfach zugreifen, ueber zeiger etc. Alles kein problem, du brauchst keinerlei IPC dazu (Shared memory, pipes etc ) . Macht man nur wenn man multiprocessing betreibt. Gleich oder spaeter halt .....

    Ne dll ist nix anderes wie ne vorkompilierte lib .... das codesegment wird nur einmal in den speicher vom BS geladen. Aber der Code selber bekommt fuer die lokalen variablen den Stack der aufrufenden exe eingeblendet .... sprich, rufst du funktionen aus der dll von einer exe auf, verwenden die alle den selben stack, sind es aufrufe von 2 exen, sind es komplett unterschiedliche stacks ... du kannst halt mit nem einfachen loadlibrary keine daten sharen (oder nur mit ganz fiesen windowseigenen tricks ) :)

    eine wichtige einschraenkung gibts noch ... weil die dll ihr instance handle(abstrakter stackzeiger) bisser verbogen bekommt, und alle speicherfunktionen auf dieses globale handel angeweisen sind, kommen die durcheinander wenn man z.b new und der einen Dll und das dazugehoerige delete in ner anderen dll/exe macht. Das gibt tolle exceptions :)

    Ciao ...