Reading variables from a forked child (Python C/API)
Jonathan Conrad
rahu at gawab.com
Fri Jul 15 14:46:04 EDT 2005
#ifdef def
Donn Cave wrote:
> Quoth MrEntropy <fake at doesntexist.dud>:
>
> | I'm having a little trouble getting an idea running. I am writing a C
> | program which is really a frontend to a Python program. Now, my C
> | program starts up, does some initialisation like initialisation of it's
> | variables and Py_Initialize() and then it fork()s. After forking the
> | child launches the python program with Py_Main() and with the parent I
> | want to be able to read the variables of the Python program. I have
> | tried many ways but cannot find a solution to do this.
>
> That's because there is no solution. After a fork, the only effect
> observable in the parent process is the return value of fork, which
> will have a non-zero value. Subsequent execution in the child process
> occurs completely independently from the parent, and leaves no trace
> whatever. So you can't read variables from memory, that were set by
> the child.
Though there is probably some solution involving a third party
such as POSIX threads, Linux has a clone(2) procedure which
fork(2) is a macro of. It is tricky to use, but allows for
having the child process have the same pid, memory, memory
mappings, file tables, etc. BSD mmap(2) is more portable and can
be used for interprocess sharing. The solution which Don Cave
provided is probably the one that Mr. Entropy needs to start
with. More specifically, ...
#else
int main (int argc, char **argv)
{
int fd0, fd1, fd2;
{
int fd_in [2], fd_out [2], fd_err [2];
pipe (fd_in); fd0 = fd_in [1];
pipe (fd_out); fd1 = fd_out [0];
pipe (fd_err); fd2 = fd_err [0];
if (!fork ()) {
dup2 (fd_in [0], 0); close (fd0);
dup2 (fd_out [1], 1); close (fd1);
dup2 (fd_err [1], 2); close (fd2);
execl ("python", "python", 0);
perror ("execution failed");
exit (1);
}
}
write (fd0, "print None\n", 11);
write (1, b, read (fd1, b, sizeof (b) /* 5 or more */));
#define write0(q...) write (fd0, "print " #q "\n", \
sizeof (#q) + 5 + 1 - 1)
write0 (True); write (1, b, read (fd1, b, sizeof (b)));
write0 (5, str (5.0), ...);
write (1, b, read (fd1, b, sizeof (b)));
return write0 (True, False, None,
True and False,
True and None,
False and None,
True and False and None) && 0;
}
#endif
More information about the Python-list
mailing list