Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hallo Leute!

Ich bin auf der suche nach einer Funktion die mir den Seitenquelltext einer Homepage in einem String ablegt.

Es Gibt die Funktion URLDownloadToFile(..); allerdings legt die mir den Quelltext in eine Datei ab.

Meine Notlösung sieht derzeit so aus:


//Laden des Quelltextes der Hompage "hp" in die Datei "DAT1"

       hr = URLDownloadToFile ( 0, hp, "DAT1", 0, 0 );   


	Sleep(100);


//Öffnen der Datei "DAT1" um den Quelltext aus der Datei auslesen zu können

	ifstream fin("DAT1");

	if (fin.is_open())

	{

                //Speichern des Quelltextes in dem String "quellcode"

		fin.read(quellcode,1000);

		fin.close();

	}

        else 

        {

                cout << "Error opening file DAT1";

        }

	Sleep(100);

Da ich komplette Webseiten durchsuchen möchte laufen bei mir ca. 16 Threads in while(true) schleifen die diese operation ständig ausführen.

Da ich mit so vielen Dateien arbeitet kommt es regelmäßig zu _CrtIsValidHeapPointer Fehlern.

Ich muss dringend diese Notlösung loswerden um endlich nicht mehr mit Dateien hantieren zu müssen!!!!

Ich hoffe einer von euch weiß einen Rat

Gruß

:new Happyman0815 :new

Geschrieben

Da ich komplette Webseiten durchsuchen möchte laufen bei mir ca. 16 Threads in while(true) schleifen die diese operation ständig ausführen.

Da ich mit so vielen Dateien arbeitet kommt es regelmäßig zu _CrtIsValidHeapPointer Fehlern.

Das Problem würde vermutlich schon verschwinden, wenn du nicht in jedem Thread denselben Dateinamen (vielleicht sogar denselben Puffer?) benutzen würdest.

Ich muss dringend diese Notlösung loswerden um endlich nicht mehr mit Dateien hantieren zu müssen!!!!

URLOpenStream Function ()

Einfacher ist aber vermutlich cURL and libcurl

Geschrieben

Hallo nochmal,

Das Problem würde vermutlich schon verschwinden, wenn du nicht in jedem Thread denselben Dateinamen (vielleicht sogar denselben Puffer?) benutzen würdest.

Der Dateiname ist bei jedem Thread bereits unterschiedlich. (DAT1, .... ,DAT16)

Ob diese nun den selben buffer verwenden weiß ich nicht.

Könntest du mir ein kleines Sample geben zu folgender Funktion?

URLOpenStream Function (...) 

Ich melde mich bis 20.00 Uhr ca. erstmal ab!

Danke schonmal für die Tipps, in cURL muss ich micht später erstmal einarbeiten.

Gruß

Happyman0815

Geschrieben

Hallo Leute!

Ich komme mit meinem Problem kaum weiter. Den Quellcode möchte ich gerne so gestallten, dass man keine externen Programme benötigt, sondern alles auch auf anderen Windows Rechnern läuft.

Ich grübel jetzt schon seit einigen Stunden über die

URLOpenStream Function ()

nach aber komm irgendwie zu keiner Lösung :rolleyes:

Wenn einer etwas mehr wissen hat über Sockets, etc. als ich wäre es nett mir ein kleines Sample für mein Problem zu geben. :old

Gruß

Happyman0815

Geschrieben

Ich habe jetzt immer noch die Lösung mit den Dateien aber zumindest habe ich keine Abstürze mehr.

Des Rätsels Lösung war:


ifstream fin;

fin.open(dat, ios::in); // <-- bei paralleler Ausführung in Threads gibt es Fehler

Wenn eine Datei in einem anderen Thread parallel geöffnet wird, gibt es den Pointer Fehler! Ich setze dafür jetzt ein Semapohren System ein:

while(!sema_file_open);

sema_file_open=false;

fin.open(dat, ios::in);

sema_file_open=true;

Damit funktioniert zumindest erstmal die Notlösung.

Gruß

Happyman0815

Geschrieben
Wenn eine Datei in einem anderen Thread parallel geöffnet wird, gibt es den Pointer Fehler!
Das kann eigentlich nicht passieren, wenn die Dateinamen wirklich unterschiedlich sind. Wie hast du das denn sichergestellt?

Ich setze dafür jetzt ein Semapohren System ein:


while(!sema_file_open);
sema_file_open=false;
fin.open(dat, ios::in);
sema_file_open=true;
[/CODE]

Damit funktioniert zumindest erstmal die Notlösung.

Wenn das funktioniert, ist es Zufall. Man kann Threads nicht mit einfachen Variablen synchronisieren (auch dann nicht, wenn sema_file_open als [i]volatile[/i] deklariert ist). Benutz die Synchonisationsprimitiven deiner Threadbibliothek.

Überhaupt ist Aktives Warten bei Multitasking oder Multithreading eine sehr schlechte Idee.

Geschrieben

Hallo!

Das kann eigentlich nicht passieren, wenn die Dateinamen wirklich unterschiedlich sind. Wie hast du das denn sichergestellt?

es gibt eine globale Variable die hochgezählt wird:


char dat[20]  = {"C:/Temp/xx/DATxx@"};

	for(i=0; dat[i] != '@'; i++); dat[i] = '\0';


	if((char) verzeichnis_temp[0]!= 'z' && (char) verzeichnis_temp[1]!= 'z')

	{

		for(i=0; dat[i] != 'x'; i++);

		dat[i]   =  (char) verzeichnis_temp[0];

		dat[i+1] =  (char) verzeichnis_temp[1];

	}

	for(i=0; dat[i] != 'x'; i++);


//Hier bekommt jeder Thread eine eigene Datei:

	dat[i] = (char) (thread_counter/10) +48;

	dat[i+1] = (char) (thread_counter%10) +48;

Ist derzeit noch "etwas" durcheinander. Der Thread Counter wird mit jedem erstellten Thread einen höher gezählt und die max. zweistellige Zahl dann in Char umgewandelt. Diese Werden dann dem Pfad hinzugefügt.

Hab das so gemacht da man mit einem Menü Thread, dynamisch Threads hinzufügen und wieder entfernen kann. Klappt soweit ganz gut habs auch bis 100 Threads mal getestet.

Wenn das funktioniert, ist es Zufall. Man kann Threads nicht mit einfachen Variablen synchronisieren (auch dann nicht, wenn sema_file_open als volatile deklariert ist). Benutz die Synchonisationsprimitiven deiner Threadbibliothek.

Überhaupt ist Aktives Warten bei Multitasking oder Multithreading eine sehr schlechte Idee.

Uff ja ich hab mir schon gedacht das das zufall ist. Das Programm schmiert auch alle paar Stunden mal wieder ab. Die Wahrscheinlichkeit eines Absturz ist aber geringer geworden :bimei

Hast du ein kleines Sample wie das vernünftig mit der Synchronisation klappt?

(Ich brauch dringend die "URL to String" Lösung :old )

Gruß

Happyman0815

Geschrieben
es gibt eine globale Variable die hochgezählt wird:

Ist derzeit noch "etwas" durcheinander. Der Thread Counter wird mit jedem erstellten Thread einen höher gezählt und die max. zweistellige Zahl dann in Char umgewandelt. Diese Werden dann dem Pfad hinzugefügt.

Auch das ist nicht sicher. Du hast nicht gezeigt, wo die Variable hochgezählt wird, aber stell dir mal vor, zwischen dem Hochzählen und dem Zusammenbasteln des Dateinamens zählt ein anderer Thread die Variable nochmal hoch. Oder zwischen den Zuweisungen von dat und dat[i+1]. Das alles kann passieren. Globale Variablen sind nicht threadsicher.

Das Programm schmiert auch alle paar Stunden mal wieder ab. Die Wahrscheinlichkeit eines Absturz ist aber geringer geworden :bimei
Das ist kein gutes Zeichen. Du kannst durch Rumbasteln die Wahrscheinlichkeit, dass so ein Synchronisierungsproblem auftritt, einschränken, aber du kannst es nie völlig ausschließen. Im besten Fall sorgst du nur dafür, dass sich der Fehler schlechter reproduzieren und damit kaum mehr aufspüren lässt.

Es kann auch sein, dass deine Basteleien bewirken, dass das Programm auf deinem Rechner stabiler läuft, auf anderen dafür umso schneller abstürzt.

Allein die Sleep-Aufrufe in deinem ersten Beitrag sind schon höchst verdächtig. Lass mich raten, damit läuft es besser? ;)

Hast du ein kleines Sample wie das vernünftig mit der Synchronisation klappt?
Threads sind kein einfaches Thema, weil Threadsynchronisierung kein einfaches Thema ist. Da du die WinAPI verwendest, wäre der erste Schritt, dass du dich in die Synchronisierungsobjekte der WinAPI-Threads einarbeitest: Events, Critical Sections, Mutexe, Semaphoren, Condition Variables (ab Vista/Server 2008).

Für dich sind vermutlich zunächst Critical Sections und die Interlocked...-Funktionen interessant:

Using Critical Section Objects (Windows)

InterlockedIncrement Function (Windows)

Geschrieben

Hallo!

Die Zuweisungen für den Dateinamen sind in dem Sinne sicher, dass Threads nur im 500 ms Takt erstellt und deletet werden können. Das sollte (auch wenn es schlecht programmiert ist) funktionieren. (und das Sleep konnte ich dank meinen pseudo Semaphoren jetzt auch raus nehmen ;) )

Bei all den anderen Faktoren hast du wohl recht und ich muss mal schauen wie ich das mit einer vernünftigen Synchronisierung in den Griff bekomme.

Es gibt denk ich mal auch Threads für C++ (nicht WinAPI)? Vielleicht sollte ich mich da mal einarbeiten damit ich später nicht von Windows abhängig bin.

Danke schonmal für die Hilfe! Ich bin in sachen Threads (ist meine erste Threadprogrammierung) auf jedenfall schonmal um einiges weiter gekommen! :)

Gruß

Happyman0815

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...