exit() und Allokation
-
Hallo, ich habe gelesen, dass exit() _exit() aufruft und sowie ich es verstanden habe dieses auch allokierten Speicher automatisch freigibt.
http://www.yolinux.com/TUTORIALS/ForkExecProcesses.htmlIn den Manpages, e.g. hier
[url] http://man.cx/exit(3)[/url]
findet sich nur etwas ueber "global memory". Da ich mir nicht sicher bin, wollte ich mal nachfragen - kann man sich darauf verlassen, dass das beenden per exit() bzw direkt per _exit() unter Linux/Unix allokierten Speicher freigibt und sich das free() am Schluss somit sparen? Mit vfork() bekaemme ich bei free() ein eckliges double-free Problem.
-
Wenn ein Prozeß beendet wird, muß das OS sowieso alle mit diesen Prozeß verknüpften Ressourcen sich zurückholen/als frei markieren, ansonsten muesste man die Kiste ja regelmäßig neu booten. Es kann ja sein das ein Prozeß z.B. durch kill -SIGKILL beendet wird order sonstwie crash't.
-
Naja, gut - also, wenn das so ist kann ich ja mir gleich generell das free() am Ende der Programme sparen?!
-
Fabeltier schrieb:
Naja, gut - also, wenn das so ist kann ich ja mir gleich generell das free() am Ende der Programme sparen?!
Ich würde es trotzdem machen, um mir die Suche nach echten Speicherlöchern zu erleichtern. Programme wie Valgrind geben dann halt viel weniger Meldungen aus.
BTW, Ich würde auch kein vfork verwenden. Aus der Manpage:
It is rather unfortunate that Linux revived this specter from the past. The BSD man page states: "This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of vfork() as it will, in that case, be made synonymous to fork(2). "
-
Fabeltier schrieb:
Naja, gut - also, wenn das so ist kann ich ja mir gleich generell das free() am Ende der Programme sparen?!
nein, auf keinen Fall. Moderne Betriebssysteme geben den Speicher frei, wenn der Prozess den Speicher nicht freigegeben hat. Als Programmiere darfst du das nicht annehmen/voraussetzen. Du musst also davon ausgehen, dass das Betriebssystem es nicht tut sondern deine Verantwortung.
Man gibt außerdem den Speicher frei, wenn man ihn nicht mehr braucht. Ich finde es nicht ok, dass man erst am Ende des Programms freigibt, obwohl der Speicher nicht mehr benötigt wird. Das kann dazu führen, dass das System Ressourcen für dich verwaltet auch wenn du sie nicht mehr benötigst und wenn du nur eine begrenzte Zahl an Speicher/Ressourcen hast, kannst du diese auch überschreiten.
Also gewöhn dir an, free zu benutzen und zwar so früh zu möglich.
-
Hallo Supertux (genial!)
..und andere,
v.a. die Antwort von Supertux ist auch meine Ansicht, ihr rennt da offene Tueren ein, ich habe diese Frage dennoch mal naiv gestellt im Hinblick auf die erste Antwort von "witte_". Mein Problem ist damit aber noch nicht geloest. Klar, kann sein dass es besser ist direkt mit fork() und somit mit separaten kopien der "sessions und etc" zu arbeiten - aber...
1. was ist denn jetz nun mit exit()??? - gibt exit() den Speicher am Schluss frei oder nicht, bzw muss/kann ich das mit valgrind nachtesten - es waere definitiv ein Vorteil beim arbeiten mit vfork(), da ich ja sonst die Speicherfreigabe extra synchronisieren muesste?
2. was benutze ich denn statt vfork() um mit gesharten Variablen in mehreren prozessen zu arbeiten - ich faende vfork() durchaus praktisch und frage mich hier schon, warum man nicht einfach vfork reimplementiert, wenn die urspruengliche Implementation Nachteile bietet?
3. arbeitet vfork() eigentlich mit synchronisiertem Zugriff auf die geteilten Variablen?
-
zu 1) exit() gibt nichts frei. Unix Betriebssysteme nehmen sich wieder jeden Speicher zurück, wenn ein Prozess sich beendet.
zu 2) Nimm fork()
zu 3) Der Zugriff wird nicht synchronisiert. Du musst dafür sorgen, dass keine Race Conditions entstehen.
-
zu 1) exit ruft außerdem alle Exit-handler, die mittels man: atexit(3) registriert wurden. Eine gewisse cleanup Funktion wird auch von exit aufgerufen. Ob an dieser Stelle den Speicher vom OS freigegeben wird, ist nicht definiert und kannst auch nicht annehmen. Am besten vergiss einfach, dass der Kernel das tut. Geh immer davon aus, dass der Kernel es nicht tut.
exit() ruft noch _exit() auf, um dem Kernel mitzuteilen, dass der Prozess endet. Wenn du nur _exit() verwendest, dann werden weder die Exit-handler noch die cleanup Funktion augerufen sondern wird der Prozess sofort (vom Kernel) beendet.
Zu 2) du kannst auch pthreads benutzen. Ich rate von vfork() ab, benutze lieber pthreads.
Zu 3) Siehe Mutex, Sempahores usw. wenn es um Synchronisierung von Prozessen geht.
-
Ok, gute Antwort - danke das hilft mir weiter