schorschi Geschrieben 4. Januar 2006 Geschrieben 4. Januar 2006 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 ? Zitieren
Guybrush Threepwood Geschrieben 4. Januar 2006 Geschrieben 4. Januar 2006 Warum gibst du niocht jedem Thread sein eigenes Recordset bzw. seine eigene Verbindung zur Datenbank? Zitieren
schorschi Geschrieben 4. Januar 2006 Autor Geschrieben 4. Januar 2006 Ich habe sogar schon versucht die Klasse unter einem andern Namen ein zweitesmal in das Projekt aufzunehmen und separat für jeden Thread einmal abzuleiten, der gleiche Fehler. Zitieren
Klotzkopp Geschrieben 5. Januar 2006 Geschrieben 5. Januar 2006 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öglichBei 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? Zitieren
schorschi Geschrieben 5. Januar 2006 Autor Geschrieben 5. Januar 2006 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. Zitieren
Klotzkopp Geschrieben 9. Januar 2006 Geschrieben 9. Januar 2006 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. Zitieren
schorschi Geschrieben 10. Januar 2006 Autor Geschrieben 10. Januar 2006 Meine Version ist die Microsoft VC++ 6.0. Zitieren
schorschi Geschrieben 29. August 2006 Autor Geschrieben 29. August 2006 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. Zitieren
Klotzkopp Geschrieben 29. August 2006 Geschrieben 29. August 2006 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. Zitieren
schorschi Geschrieben 29. August 2006 Autor Geschrieben 29. August 2006 @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 ? Zitieren
Klotzkopp Geschrieben 29. August 2006 Geschrieben 29. August 2006 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. Zitieren
schorschi Geschrieben 29. August 2006 Autor Geschrieben 29. August 2006 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. Zitieren
schorschi Geschrieben 30. August 2006 Autor Geschrieben 30. August 2006 Hat sich erledigt, habe es hinbekommen. Danke für eure Antworten Zitieren
Empfohlene Beiträge
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.