Antwort schreiben  Thema schreiben 
Verfasser Nachricht
Gigor
Durchstarter
**


Beiträge: 72
Gruppe: User
Registriert seit: Jun 2011

Status: Offline
Danke erhalten: 18
Beitrag: #1
xPSP  Problem mit Threads

Hi,
bin gerade dabei in C einen miniHTTP Server zu basteln, und soweit sogut er liefert auch schon erste Testseiten ausSmile
Ich hab es, der einfach halt halber, so gemacht, dass für jede datei eine neue Verbindung und ein neuer Thread gestartet wird.
Soweit funktioniert das auch, nur nach kurzer Zeit hängt es sich bei der Funktion sceKernelStartThread auf, freezt und schaltet sich schließlich auf selbst aus (unsanft, wie wenn man en Akku rausmacht..)
Weiß jemand woran es liegen könnte, wie man es behebt oder umgeht (also einen Fehler frühzeitg erkennen?)

Code:
void klientThreadStarten(int socket){
    char name[32];
    sprintf(name,"Client%d",gesamtAnfragen);
    SceUID thid = sceKernelCreateThread(name,klientBedienen,0x18,0x10000,0,NUL L);   //Zahlenwerte von dem Beispiel in der Dokumentation
    printf("Starte Thread %s : %d...",name,thid);
    
//Hier hängt sichs auf:
    int tRueck = sceKernelStartThread(thid,sizeof(socket),&socket);
    printf("Thread %s gestartet: %d\n",name,tRueck);
    
}


Danke schonmalSmile
Gigor

Dieser Beitrag wurde zuletzt bearbeitet: 13.01.2012 18:13 von Gigor.

13.01.2012 18:13
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
vista200
Head of Awesomeness
***


Beiträge: 189
Gruppe: User
Registriert seit: Jul 2009

Status: Offline
Danke erhalten: 139
Beitrag: #2
xPSP  RE: Problem mit Threads

Der RAM der PSP ist voll. Oder der zugewiesene Speicher des gesamten Programms. Je nachdem, was zuerst eintrifft Wink
Ich glaube auch, dass 65536 Byte für eine Anfrage vielleicht etwas zu viel sind. Reichen nicht 4096 Byte (0x1000) aus?

Das Problem ist, dass, wenn ein Thread erstellt werden soll und dieser mehr RAM beansprucht, als verfügbar ist, dann liefert sceKernelCreateThread einen negativen Wert zurück.
Dieser negative Wert ist entsprechend die Fehlermeldung und lässt sich in der Dokumentation nachschlagen.
Du solltest daher überprüfen, ob thid größer als null ist und erst dann sceKernelStartThread aufrufen oder noch eine Sekunde warten und dann erneut versuchen den Thread zu erstellen.

Mein Lösungsvorschlag:

Code:
void klientThreadStarten(int socket){
    char name[32];
    sprintf(name,"Client%d",gesamtAnfragen);
    SceUID thid;
    // Solange kein Thread erstellt werden konnte, wird versucht ein Thread zu erstellen. Dies wird solange versucht, bis es funktioniert
    while ((thid = sceKernelCreateThread(name,klientBedienen,0x18,0x10000,0,NUL L)) /* hier ein "kleiner als"-Zeichen einfügen */ 0) {
        printf("Thread %s: Warte auf Ressourcen\n", name);
        sceKernelDelayThread(100);
    }

    // Erfolg: Der Thread hat genug Speicher bekommen
    printf("Starte Thread %s : %d...\n",name,thid);
    int tRueck = sceKernelStartThread(thid,sizeof(socket),&socket);
    printf("Thread %s gestartet: %d\n",name,tRueck);
    
}


Außerdem solltest Du eventuell statt Dir die Rückgabewerte als Dezimalzahl darstellen zu lassen sie als hexadezimale Zahlen im Format "0x%08X" ausgeben lassen. Damit kannst Du direkt die Fehlercodes kontrollieren und erhältst keinen "Thread -270123112312". Positive Werte (im Falle des Erfolgs Smile ) werden dann z.B. als "0x00000004" für "4" dargestellt. Wie gesagt, es ist nur eine Empfehlung. Wink

Sorgst Du denn auch dafür, dass alte, abgelaufene Threads wieder gelöscht bzw. deren Speicher freigegeben wird? Wie organisierst Du die Threads? Speicherst Du sie in einer Liste oder startest Du sie einfach?
Wenn sie abgelaufen sind solltest Du am Ende ein sceKernelExitDeleteThread(0); in der klientBedienen-Methode aufrufen.

Hoffe, das hilft Dir erstmal. Wenn was is... Einfach melden Big Grin


Dieser Beitrag wurde zuletzt bearbeitet: 13.01.2012 19:00 von vista200.

13.01.2012 18:55
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
Folgende User bedanken sich:
Gigor (Jan-14-2012), ~Hook~ (Jan-14-2012), -blue7 (Jan-14-2012), The Real Enigma87 (Jan-14-2012)
The Real Enigma87
Legende
*****


Beiträge: 1.345
Gruppe: User
Registriert seit: May 2010

Status: Abwesend
Danke erhalten: 712
Beitrag: #3
RE: Problem mit Threads

Was geht denn hier abWink

Viele der neuen Member hier haben in Sachen Coding und Programmierung echt was draufWink

Hätte ich nicht gedachtWink

aber ich finde es cool^^



"Heroes??? There is no Such Thing."

Mandarin - Iron Man 3
14.01.2012 03:03
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
Gigor
Durchstarter
**


Beiträge: 72
Gruppe: User
Registriert seit: Jun 2011

Status: Offline
Danke erhalten: 18
Beitrag: #4
xPSP  RE: Problem mit Threads

Hi,
Dankschön für die ausführliche Antwort.
Also bis jetzt mach ich das mit den Threads so, dass es eine Maximale Anzahl an laufenden Verbindungen (also auch Threads) gibt, und immer wenn ein Thread gestartet wird eins hoch zählt, bzw sich mit sceKernelExitDeleteThread beendet, wieder eins nach unten. Wenn eine Maximale Anzahl an Verbindungen erreicht ist, sollte es eigetnlich erst garkeine mehr annehmen. Macht er auch nicht..
Bis jetzt hab ich es auf 1.
Nach ner Zeit hatter sich dann aufgehängt, obwohl eigetnlich nur 3 Threads gleichzeitig laufen sollten (Der Main, einer Für ein Client und einer fürs steuern)


So, wenn ich die Stacksize auf 0x1000 (= 4096 Bytes) verringer geht garnichts, dann hängts sich gleich beim allerersten mal auf, allerdings ohne die "Warten auf Ressourcen" - Warnung auszugeben, die Schleife ist wohl übersprungen. 4kB sind wohl zu wenig..

Wenn ich Stacksize auf 0x10000 (= 64 kb) lasse, und die Max. Verbindungen auch auf 1. lasse (also nur eine UserAnfrage), hängt es sich zwar nicht mehr auf, aber nach ner Zeit isses trotzdem kaputt, weil anscheindend der Bedienthread nix mehr macht und so keine Verbindung mehr frei wird. Ich kann aber noch normal mit Kreis beenden (also der Kontroll-Thread läuft auch noch).Vielleicht ein fehlender Timeout oder so..

Wenn ich die max. gleichzeitigen Verbindungen auf 2 hochsetze, hängt es sich noch auf, an der gleichen stelle, aber es kommt keine Warnung (also die Schleife wird wohl übersprungen)
[Gerade beim Testen sehr komisch: Mit telnet/IE konnte ich auf server connecten, firefox hat gestreikt..]


Reicht es, einen Thread mit sceKernelExitDeleteThread zu beenden oder muss man noch irgendwelche aufräumarbeiten machen?

Kann es vielleicht sein, dass sich 2 Threads beißen wenn die aufs Netzwerk zugreifen oder so? Oder die sich sonst irgendwie nicht abkönnen?

Ich gugg weiter durch, vll hab ich noch irgendwo nen Bock, aber irgendwas scheint es damit zu tun zu haben.
Gigor

14.01.2012 16:39
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
vista200
Head of Awesomeness
***


Beiträge: 189
Gruppe: User
Registriert seit: Jul 2009

Status: Offline
Danke erhalten: 139
Beitrag: #5
xPSP  RE: Problem mit Threads

Gigor :
Nach ner Zeit hatter sich dann aufgehängt, obwohl eigetnlich nur 3 Threads gleichzeitig laufen sollten (Der Main, einer Für ein Client und einer fürs steuern)

Hast Du einen Debug-Output, in dem Du sehen kannst, welcher Thread "stirbt" bzw. abstürzt? Was macht der "Steuer"-Thread?

Gigor :
So, wenn ich die Stacksize auf 0x1000 (= 4096 Bytes) verringer geht garnichts, dann hängts sich gleich beim allerersten mal auf, allerdings ohne die "Warten auf Ressourcen" - Warnung auszugeben, die Schleife ist wohl übersprungen. 4kB sind wohl zu wenig..

Hast Du noch andere Werte ausprobiert? 2kB z.B.?

Gigor :
Wenn ich Stacksize auf 0x10000 (= 64 kb) lasse, und die Max. Verbindungen auch auf 1. lasse (also nur eine UserAnfrage), hängt es sich zwar nicht mehr auf, aber nach ner Zeit isses trotzdem kaputt, weil anscheindend der Bedienthread nix mehr macht und so keine Verbindung mehr frei wird. Ich kann aber noch normal mit Kreis beenden (also der Kontroll-Thread läuft auch noch).Vielleicht ein fehlender Timeout oder so..

Wie ist denn der Main-Thread aufgebaut? Du lässt das Programm so lange laufen, wie Verbindungen eingehen, richtig? Also in etwa so:

Code:
while (((accept = accept()) /*größer-als-zeichen*/ 0) /* und und */ threadZaehler /* kleiner-als-zeichen*/ 1) {
// Thread erstellen und Socket-Nummer mitgeben
// Thread-Zähler + 1
}


Wenn es so läuft, dann wird der Main-Thread abgebrochen, weil der Thread-Zähler ja hochgesetzt wurde... Ich bin mir nicht sicher, welche Bedingungen für die Erfüllung des Schleifenbedingung bei Dir erforderlich sind.

Gigor :
[Gerade beim Testen sehr komisch: Mit telnet/IE konnte ich auf server connecten, firefox hat gestreikt..]

Firefox und alle anderen Server haben die Angewohnheit, mehrere Verbindungen zu öffnen und mehrere Daten gleichzeitig anzufordern. Hier lässt sich meist nur mit einem "einfachen" Telnet-Client arbeiten.
Liefert der Server denn auch den HTTP-Header mit, den der Browser braucht, um die Anfrage erfolgreich verarbeiten zu können?

Gigor :
Reicht es, einen Thread mit sceKernelExitDeleteThread zu beenden oder muss man noch irgendwelche aufräumarbeiten machen?

Das sollte reichen. Es sei denn, du allozierst via malloc() im Thread noch Speicher für die Testseiten oder so... Den solltest Du vor sceKernelExitDeleteThread() noch mit free(void*) freigeben, ansonsten entstehen Memory Leaks, die dazu führen, dass der belegte (aber nicht mehr gebrauchte) Speicher weiterhin als belegt gilt. Hier kannst Du z.B. beim Debuggen mit PSPLink die Belegung der RAM-Partitionen während der Ausführung einsehen.

Gigor :
Kann es vielleicht sein, dass sich 2 Threads beißen wenn die aufs Netzwerk zugreifen oder so? Oder die sich sonst irgendwie nicht abkönnen?

Eigentlich ist das nicht der Fall. Und falls doch, dann setze eine globale Variable "sendetGerade" auf "1", sobald ein Thread etwas senden möchte und wieder auf "0", sobald er damit fertig ist. Alle anderen Threads musst Du dann so programmieren, dass sie so lange mit dem Senden warten, bis "sendetGerade" wieder auf "0" steht. Aber aufgrund vom TCP-Protokoll sollte eigentlich jedes Paket - sofern fehlerfrei abgesendet - auch fehlerfrei beim Empfänger ankommen.

Du darfst mir gerne mal Deinen Quelltext schicken, ich habe mal ein ähnliches Projekt gehabt, allerdings nicht weiterverfolgt... Ich glaube aber auch, dass ein Webserver Anfragen nicht threaden muss, sondern sie nacheinander abarbeiten kann. Nur so ein Gedanke...


Dieser Beitrag wurde zuletzt bearbeitet: 15.01.2012 21:05 von vista200.

15.01.2012 21:02
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
Folgende User bedanken sich:
Gigor (Jan-22-2012)
Gigor
Durchstarter
**


Beiträge: 72
Gruppe: User
Registriert seit: Jun 2011

Status: Offline
Danke erhalten: 18
Beitrag: #6
xPSP  RE: Problem mit Threads

Hi mal wieder,
hat jetzt en bisschen gedauert, hatte wenig zeit und bis ich psplink zum laufen gebracht hab..
Bin schon etwas weiter gekommen, aber erstmal die Lage.:
Also ich meine Hauptschleife ist in etwa so aufgebaut:

Code:
while(1){
if(verbdinung >= verbMax){continue}
/*verbindungen annehem*/
}

Stacksize hab ich jetzt auf 32kb.
Und mit dem HTTP sollte eigentlich funktionieren, Firefox stellt die Testseiten (C von a bis z offline Version^^) ganz gut dar, bisses halt abstürztSad

Also ich glaub ich hab ein Hauptproblem gefunden.
Ich hatte nur eine Adressenstruktur für alle eingehenden Verbindungen (hab ich als nicht wichtig erachtet.) und das geht wohl nicht wenns mehrere gleichzeit sind^^:

Nungut, aber leider klappts immer noch nicht, irgendwann (ziemlich früh sogar) hängt sich ein Klientthread auf.
Mit der PSP-Link ausgabe kann ich bis jetzt garnix anfangen, nur dasses ein ClientThread verbocktSmile
Die Andern Threds gehn aber noch. [Edit: Ist wohl nur wenn ich in PSP-LInk die prx starte, bei der normalen eboot hängt sichs ganz auf..]

Spoiler: (anzeigen)
Hier mal der gesamte Quelltext, falls du mal drüberguggen willst. Ist aber ziemlich unprofessionell^^
Spoiler: (anzeigen)
[das stellt das manche Zeichen falsch dar..]

dankende grüße
Gigor

Edit:
So, ich bin ein ganz kleinen Schritt weiter, der 2. Thread hängt sich wohl ganz am Anfang auf, direkt bei "empfange Anfrage"
Spoiler: (anzeigen)
Neuer Edit:
Jetzt ist sogar einmal der user_main abgeschmiert.. ich glaub ich geb auf...[Ok ist en anderes Error sehr ich gerade (load adresse/inst fetch), resultiert vll aus error 1]

Hauptthread abgeschmiert (anzeigen)

Dieser Beitrag wurde zuletzt bearbeitet: 25.01.2012 18:45 von Gigor.

22.01.2012 17:42
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
Gigor
Durchstarter
**


Beiträge: 72
Gruppe: User
Registriert seit: Jun 2011

Status: Offline
Danke erhalten: 18
Beitrag: #7
xPSP  RE: Problem mit Threads

Falls es noch jemand interessiert hab mich mal wieder drangesetzt und hab jezt ein halbwegs "stabilen" Server hinbekommen.
(Firefox hängt bei großen seiten zwar, aber der server läuft nochWink Also einfache Bilder oder so werden aber schon angezeigt)
Wer intersse hat einfach melden.
PS: Hab das Problem umgangen indem ich bei der Threaderzeugung keine Argumente übergeben hab und alles mit Globalen Variablen gemacht hab

Dieser Beitrag wurde zuletzt bearbeitet: 30.05.2012 18:30 von Gigor.

30.05.2012 18:29
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
Antwort schreiben  Thema schreiben 

Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
xPSP Syscalls? Threads? Fly Destination 1 942 20.12.2010 21:00
Letzter Beitrag: HacKmaN

Druckversion anzeigen
Thema einem Freund senden
Thema abonnieren | Thema zu den Favoriten hinzufügen




» zum Seitenanfang