Problem mit fork() in der C-API

Hallo Gruppe, ich habe einen C-Code an Python mit der C-API angebunden, der u.a. einen fork() mit einem exit() macht. Der C-Code sieht etwa so aus (library und Code zusammengeworfen): -------------------8<------------------------------ #include <unistd.h> #include <Python.h> static PyObject *bar(PyObject *self) { pid_t childpid = fork(); if (childpid == 0) exit(0); sleep(1); return Py_BuildValue("s", "Ready."); } static PyMethodDef foo_methods[] = { {"bar", (PyCFunction)bar, METH_NOARGS, "Bla"}, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initfoo(void) { Py_InitModule("foo", foo_methods); } -------------------8<------------------------------ Das Beispielmodul kann man mit einem trivialen setup.py einbinden: -------------------8<------------------------------ from setuptools import setup, Extension module1 = Extension('foo', sources = [foo.c']) setup (name = 'foo', packages = ['foo'], ext_modules = [module1]) -------------------8<------------------------------ Wenn ich damit folgendes mache: -------------------8<------------------------------ a = open("a.dat", "w"); for i in range(10): foo.bar() a.write(" %i" % i) a.close() -------------------8<------------------------------ dann sieht "a.dat" so aus: -------------------8<------------------------------ 0 0 1 0 1 2 0 1 2 3 0 1 2 3 4 0 1 2 3 4 5 0 1 2 [...] -------------------8<------------------------------ Offenbar versucht jedes Kindprogramm den Cache zu leeren. Ein Ersetzen von exit() im C-Code durch _exit() ändert daran jedoch auch nichts. Eine analoge Funktion die man direkt aus C heraus aufruft, zeigt dieses Verhalten nicht, daher scheint es sich um ein CPython-Spezifikum zu handeln. Warum ist das so und wie kann ich das verhindern? Viele Grüße Ole

Am 31.01.2012 14:24, schrieb Olе Streicher:
Hallo Gruppe,
ich habe einen C-Code an Python mit der C-API angebunden, der u.a. einen fork() mit einem exit() macht.
Wenn du selbst einen Fork machst, musst du auch die passenden Hooks verwenden. Das ist schon mal ein Bug in deinem Code. http://docs.python.org/c-api/sys.html#PyOS_AfterFork Christian

On 31.01.2012 14:33, Christian Heimes wrote:
Am 31.01.2012 14:24, schrieb Olе Streicher:
Hallo Gruppe,
ich habe einen C-Code an Python mit der C-API angebunden, der u.a. einen fork() mit einem exit() macht.
Wenn du selbst einen Fork machst, musst du auch die passenden Hooks verwenden.
Interessantes Phänomen. Ich vermute mal, das Problem hat eher mit vererbten Filepointern im Zusammenspiel mit Pythons Fileobjekten zu tun. In der fork Manpage stehen ja ein paar Dinge, die Child-Prozesse nicht erben. Ich würde mal in den Python-Sourcen schauen, ob das Fileobjekt evtl. davon betroffen ist.
Warum ist das so und wie kann ich das verhindern?
Warum das so ist, weiß ich nicht, aber ein a.flush() direkt nach dem a.write(..) stellt das erwartete Verhalten wieder her. Chris

On 01.02.2012 16:27, Christopher Arndt wrote:
On 31.01.2012 14:33, Christian Heimes wrote:
Am 31.01.2012 14:24, schrieb Olе Streicher: Warum ist das so und wie kann ich das verhindern?
Warum das so ist, weiß ich nicht, aber ein a.flush() direkt nach dem a.write(..) stellt das erwartete Verhalten wieder her.
Mit Python 3 (getestet mit 3.2.2) funktioniert es übriges, wie erwartet. Siehe Py3-Version der Extension im Anhang. Chris
participants (3)
-
Christian Heimes
-
Christopher Arndt
-
ole-usenet-spam@gmx.net