Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hallo,

ich habe da eine Problem mit Threads.

Mein Progr. soll mit einem Thread permanten auf einem Socket horchen.Bei einkommenden Daten sollen diese verarbeitet und in einer Datenbank gespeichert werden.Mit einem andern Thread möchte ich paralell dazu einen Dialog öffnen können und dort die gleiche Datenbank bearbeiten. Mal abgesehen davon das ich mir noch gedanken über den zeitgleichen Zugriff machen muß scheitere ich schon viel früher.

Ich kann beides separat aufrufen und nutzen allerdings wenn z.B. Daten auch dem Socket eintreffen und verarbeitet werden und ich anschließend den Dialog öffne dann stürzt das programm. Umgekehrte Reihenfolge genauso.

Die Fehlermeldung Vorgang read konnte auf dem Speicher nicht durchgeführt werden ist in beiden Fällen auf der gleichen Adresse.

Der Fehler liegt beim Zugriff auf die Recordset und meiner eigenen von CDaoDatabase abgeleiteten Klasse. Laut "Visual C++6.0 Inside" ist der threadübergreifende Zugriff auf MFC Objekte nicht möglich (außer bei einfachen Objekten wie CString oder ähnlich).

Jetzt meine Frage, wie bekomme ich den Zugriff auf meine Recordsets hin ? Da kann ich mir nicht vorstellen das das nicht klappen soll. Wie bekomme ich zewi unterschiedliche Adressräume hin ?

Geschrieben
Die Fehlermeldung Vorgang read konnte auf dem Speicher nicht durchgeführt werden

[...]

Der Fehler liegt beim Zugriff auf die Recordset und meiner eigenen von CDaoDatabase abgeleiteten Klasse. Laut "Visual C++6.0 Inside" ist der threadübergreifende Zugriff auf MFC Objekte nicht möglich

Bei einem Threadproblem mit den MFC sollte das Programm eigentlich mit einer fehlgeschlagenen Assertion abbrechen, nicht mit einer AV. Was sagt denn der Debugger? Wie sieht der Call stack (Aufrufliste) zum Zeitpunkt des Absturzes aus?
Geschrieben

Meinst Du mit CallStuck meinen Quellcode bei welcher Anweisung der Absturz passiert ?

Wenn ich die Database bzw. Recordset öffnen will.

Definitiv ist das beide beim Versuch sie zu öffnen geschloßen sind.Also der Fehler kommt nicht daher.

Wenn ich Daten per Socket empfange und den Dialog öffne mit einer openrecordset Methode in InitDialog() habe jetzt ich die Fehlermeldung:

Unbehandelte ausnahme in server.exe(DAO350.DLL); 0xc0000005:Access Violation.

Wenn ich mit ok bestätige bekomme ich eine Dissasemblierung Liste wo der Marker bei folgender Zeile steht:

044C65D3 cmp dword ptr [eax+38h],0

Ich hoffe Du kannst was damit anfangen.

Variablenüberwachung per debugger ok, mit dem Debugger schrittweise den Fehler suchen auch ok aber mehr habe ich mit dem Debugger nicht drauf.

Geschrieben
Meinst Du mit CallStuck meinen Quellcode bei welcher Anweisung der Absturz passiert ?
Nein, der Call stack (in der deutschen Version "Aufrufliste" ist ein spezielles Fenster beim Debuggen. Wenn du Version und Sprache deines VC nennst, kann ich dir genauer sagen, wo du es findest.

In dem Fenster findest du eine Auflistung aller Funktionsaufrufe, die zum Crash geführt haben.

  • 7 Monate später...
Geschrieben

Ist zwar Ewigkeiten her aber wenns geht möchte ich diesen Thread gerne wieder aufleben lassen. Am Thema hat sich nix geändert. Bei Absturz zeigt der Stack folgendes:

DAO350! 044c65d3()

DAO350! 044d08fb()

24448b00()

womit ich ehrlich gesagt wieder mal nix anfangen kann. Eines wunderte mich nur.Wenn ich den Haltepunkt vor der OpenDB anweisung setze, und mit der Mouse über meine Vaiable gehe zeigt er mir weder Adresse oder Inhalt an im Kontex an.

Na ja aufgeschoben ist nicht aufgehoben. Bin dankbar für jede Hilfe.

Geschrieben
Wenn ich den Haltepunkt vor der OpenDB anweisung setze, und mit der Mouse über meine Vaiable gehe zeigt er mir weder Adresse oder Inhalt an im Kontex an.

Möglicherweise ist zu diesem Zeitpunkt der Stack bereits zerschossen. Zeig doch mal, wie du die Daten vom Socket einliest.

Geschrieben

@Klotzkopf

Die Sache mit dem Zugriff per Thread auf meine Datenbankklasse hat sich nach der letzten Nacht etwas geändert. Im Netz ist wohl hauptsächlich zu lesen, das viele die Finger davon lassen da angeblich die Daoschnittstelle nicht Threadsicher sei. Wie ich inzwischen nachlesen konnte, machen es wohl einige Leute so das Sie mit AfxDaoInit() und AfxDaoTerm() arbeiten, sprich wenn der zweite Thread auf die Datenbankklasse zugreift muß neu initialisiert werden.

Na ja der Programmabsturz hat sich nun insoweit verlagert das ich nun mit der Socket- & der Dialogklasse auf meine Datebanbankklasse zugreifen kann, aber:

Ich greife von beiden Seiten aus mit einem Pointer auf die Datenbankklasse zu und setze bei benutzung eine static flag, die kommen sich also nicht in die Quere(überprüft). Wenn ich allerdings mit dem Dialog drauf zugreife, erscheint die Meldung "Datenbank exclusiv von .. genutzt und dadurch gesperrt".

Merkwürdigerweise bekomme ich immer diese Meldung wenn vorher der Socket den Zugriff hatte.(Der Socket hat auch sauber gearbeitet und den Connect wieder geschloßen,auch überprüft)

Greift im Anschluß der Socket wieder zu (kein fehler) und ich öffne den Dialog dann verabschiedet sich beim schließen(!) des Dialoges beim zweiten Aufruf das Programm. Es ist eigentlich völlig eagl wer den ersten Zugriff hat, der Dialog bringt das ganze immer wieder zum abschmieren, allerdings erst nach ein paar Zugriffen.

Die Fehlermeldung bein abschmieren ist wieder Access Violation diesmal in der MFC42.DLL..Allerdings diesmal durch AfxDaoTherm() verursacht.

und hier komme ich aus:

void AFXAPI AfxDaoTerm()

{

_AFX_DAO_STATE* pDaoState = AfxGetDaoState();

// Close any CDaoWorkspaces left around

void* pvKey;

void* pvObject;

POSITION pos = pDaoState->m_mapWorkspaces.GetStartPosition();

while (pos != NULL)

{

pDaoState->m_mapWorkspaces.GetNextAssoc(pos, pvKey, pvObject);

((CDaoWorkspace*)pvObject)->Close();

}

pDaoState->m_mapWorkspaces.RemoveAll();

// Clean up engine object if necessary

if (pDaoState->m_pDAODBEngine != NULL)

{

pDaoState->m_pDAODBEngine->Release();<<<<<------

Was ich zunächst einmal gern versuchen würde ich die gesperrtmeldung wegzubekommen. Obwohl m_pDaodatabase geschloßen wurde, wird sie ja immer noch blokiert. Ich habe schon versucht per localer deklaration mit new und delete in der Socket und Dialogklasse zu hantieren, kein Erfolg. Ich müßte irgendwie die die Verbindung bzw. Datenbankklasse neu initialisieren denke ich.

Quellcode ist hier viel zu viel und in der Summe der Klassen denke ich mal überhaupt nicht übersichtlch. Witzigerweise habe ich durch das überprüfen erst mal SendMessage() kennengelernt um per thread auf die Statusleiste zuzugreifen, wenigstens etwas :marine

Was meint Du ?

Geschrieben

Ich würde dir dringend dazu raten, entweder dein Programm so umzustellen, dass nur ein Thread auf die Datenbank zugreift, oder eine threadsichere Datenbankschnittstelle zu benutzen. Alles Andere ist in meinen Augen ein blutiger Hack.

Du kannst übrigens über eine einfache statische Variable keine sichere Threadsynchronisierung erzeugen.

Geschrieben

das mit der statischen ist mein blutiger anfang mit Threads, das das so nicht sicher ist hatte ich schon vermutet. Hast Du dich schon mal mit der Engine 3.5 beschäftigt ? Ich denke mal wenn ich meine Klasse so Umbau das ich von der Engine aus alles erstelle, ist das vielleicht ein Lösungsansatz. Alles in einen Datenbankthread zu packen wäre der letzte Ausweg, aber durchaus denkbar.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...