2010-11-20 3 views
0

Ich habe ein Programm, in dem ein Master-Prozess generiert N Arbeiter, die invertieren, jeder, jede Zeile eines Bildes, mir am Ende ein umgekehrtes Bild geben. Das Programm verwendet Shared Memory und Posix Semaphore, unbenannte Sems, genauer gesagt, und ich benutze shmctl mit IPC_RMID und sem_close und sem_destroy in der Funktion terminate(). Allerdings, wenn ich das Programm mehrmals ausführen, manchmal gibt es mir einen Segmentierungsfehler und ist in der ersten Shmget. Ich habe bereits meinen shmmax-Wert im Kernel geändert, aber das kann ich nicht mit dem shmall-Wert machen, ich weiß nicht warum.Probleme beim Ausführen eines Programms mit gemeinsam genutztem Speicher; Seg Fehler manchmal; Shmmax und Shmall haben etwas damit zu tun?

Kann mir bitte jemand helfen? Warum passiert das und warum ist es nicht die ganze Zeit? Der Code scheint in Ordnung zu sein, gibt mir, was ich will, effizient und so ... aber manchmal muss ich Ubuntu neu starten, um es wieder ausführen zu können, auch wenn ich die Ressourcen freigebe.

Bitte erleuchten Sie mich!

EDIT:

Hier sind die 3-Dateien benötigt, um den Code + die Make-Datei auszuführen:
http://pastebin.com/JqTkEkPv
http://pastebin.com/v7fQXyjs
http://pastebin.com/NbYFAGYq

http://pastebin.com/mbPg1QJm

Sie haben es so laufen./invertiere someimage.ppm outimage.ppm (teste jetzt bitte mit einem kleinen)

Hier sind einige Werte, die wichtig sein können:

$ipcs -lm 
------ Shared Memory Limits -------- 
max number of segments = 4096 
max seg size (kbytes) = 262144 
max total shared memory (kbytes) = 8388608 
min seg size (bytes) = 1 

$ipcs -ls 

------ Semaphore Limits -------- 
max number of arrays = 128 
max semaphores per array = 250 
max semaphores system wide = 32000 
max ops per semop call = 32 
semaphore max value = 32767 

EDIT: die seg Fehler behoben wurde! Ich habe ein ** Array im Shared Memory zugewiesen und das war ein bisschen komisch. Also habe ich nur ein Segment für ein * Array zugewiesen und voilà. Wenn Sie möchten, überprüfen Sie den neuen Code und Kommentar.

+3

Das wird schwierig ohne Zugriff auf den Code. – Lagerbaer

+0

Wenn Sie in der Lage sind, auf den Codebereich einzugrenzen, der den Segmentierungsfehler verursacht, fügen Sie diese fehlerhaften Zeilen hier ein. – vpit3833

+0

Ich habe den Beitrag bearbeitet, damit Sie die Links mit dem gesamten Quellcode sehen können – neverMind

Antwort

1

Jetzt, wo Sie Ihren Code veröffentlicht haben, können wir ein bisschen mehr sagen.

Ohne alles im Detail gelesen zu haben, finde ich die Bereinigungsphase von main verdächtig. In der Tat scheint es mir, dass all Ihre Arbeitsprozesse auch diese Bereinigungsphase durchführen werden.

Nach der Gabelung sollten Sie deutlicher unterscheiden, was main tut und was die Arbeiter tun. Alternativen:

  • Ihr Hauptprozess wait auf den pid s der Arbeiter und machen den Rest der Verarbeitung und Bereinigung nur dann nur konnten.
  • Alle Worker-Prozesse konnten in main nach dem Aufruf an worker zurückgeben.
  • Anruf 10 am Ende des Worker Funktion.

bearbeitet nach dem Code Update:

denke ich immer noch eine bessere Lösung, die ein klassisches wait für alle Prozesse zu tun wäre.

Sehen wir uns nun Ihren Arbeitsprozess an. Tatsächlich enden diese niemals, es gibt keine break Anweisung in der while (1) Schleife. Ich denke, was passiert ist, dass wenn es keine Arbeit mehr zu

  • getan werden die Arbeiter in sem_wait(sem_remaining_lines)
  • Ihr Hauptprozess von
  • die Kündigung wird benachrichtigt stecken
  • es die sem_remaining_lines
  • zerstört
  • der Arbeiter kehrt von sem_wait zurück und fährt fort
  • seit ist auch schon zerstört (Oder vielleicht sogar unmapped) das Warten auf kehrt sofort
  • jetzt versucht es auf die Daten zuzugreifen, und je nachdem, wie weit die main Prozess auf Zerstörung bekam die Daten abgebildet wird oder nicht, und die Arbeiter Abstürze (oder nicht)

Wie Sie sehen können, haben Sie viele Probleme dort. Was würde ich tun, um diese aufzuräumen ist

  • waitpid bevor die gemeinsamen Daten
  • sem_trywait statt der 1 in while (1) zerstören. Aber vielleicht habe ich Ihren Kontrollfluss nicht vollständig verstanden. In jedem Fall geben Sie ihnen eine Abbruchbedingung.
  • Erfassen Sie alle Rücksendungen aus System Funktionen, insbesondere die sem_t Familie. Diese können durch IO unterbrochen werden, so müssen Sie definitiv müssen für diese auf EINTR überprüfen.
+0

Ok, ich werde versuchen, diese Änderungen zu machen, und dann werde ich es posten. Danke – neverMind

+0

Sie können meinen ersten neuen Link in meinem Beitrag sehen, bitte? Ich habe mehr oder weniger die Änderungen gemacht, die ich sagte, aber ohne Erfolg ... Ich habe immer noch Probleme mit Shmget nach 5-6 Läufen ... :( – neverMind

+0

Ich änderte ein bisschen, anstatt sh_mm zu einem ** Array I zuzuweisen habe einen einfachen Zeiger gemacht, weil shmat zurückkehrt (void) *. Also, der Seg-Fehler wurde gelöst. Nun habe ich einige Änderungen basierend auf dem, was du mir gesagt hast, könntest du nach einigen Inkonsistenzen suchen? Ich werde den 1. Link erneut editieren – neverMind

3

Wenn alle Ihre sem_t POSIX Semaphore unbenannte sind, sollten Sie nur sem_init und sem_destroy auf sie verwenden und nie sem_close.

Verwandte Themen