473,396 Members | 1,914 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

os.fork() different in cgi-script?

Hi,

following code:

#!/usr/bin/python

import os
import sys

def main():
print "Content-Type: text/plain\n\n"
print os.getpid()

childPID = os.fork()
if childPID == 0:
sys.exit()
else:
os.wait()

if __name__ == "__main__":
main()

when run on a shell, gives the result:
---------------------------
Content-Type: text/plain
20953
----------------------------

but run as a cgi-script it gives:
---------------------------
21039
Content-Type: text/plain
21039
---------------------------
So it looks the main() is run 2 times.
Is it so? And if yes, why?

I googled for this but only found a similar question from 1997 and no
answer.

Ciao, Andreas

Jul 18 '05 #1
13 5262
Sorry, forgot:

this is Python 2.2.1, apache 1.3.26 on SuSE 8.1

Andreas
Jul 18 '05 #2
"Andreas Kuntzagk" <an**************@mdc-berlin.de> writes:
def main():
print "Content-Type: text/plain\n\n"
print os.getpid()

childPID = os.fork()
if childPID == 0:
sys.exit()
else:
os.wait()

if __name__ == "__main__":
main()

when run on a shell, gives the result:
---------------------------
Content-Type: text/plain
20953
----------------------------

but run as a cgi-script it gives:
---------------------------
21039
Content-Type: text/plain
21039
---------------------------
So it looks the main() is run 2 times.
Is it so? And if yes, why?


Probably because stdout is being buffered here. The pid got written in the buffer (but not yet actually printed), then the process was forked, then the buffer got flushed (written out) by each child.

One solution would be to make sure everything is flushed before you fork.

Mike

--
Mike Coleman, Scientific Programmer, +1 816 926 4419
Stowers Institute for Biomedical Research
1000 E. 50th St., Kansas City, MO 64110
Jul 18 '05 #3
On Wed, 02 Jul 2003 09:50:03 +0000, Michael Coleman wrote:
Probably because stdout is being buffered here. The pid got written in
the buffer (but not yet actually printed), then the process was forked,
then the buffer got flushed (written out) by each child.

One solution would be to make sure everything is flushed before you
fork.


Thanx, that's it. Is it possible/advisable to make stdout unbuffered?

Andreas
Jul 18 '05 #4
"Andreas Kuntzagk" <an**************@mdc-berlin.de> writes:
following code: print "Content-Type: text/plain\n\n"
print os.getpid()

childPID = os.fork()
if childPID == 0:
sys.exit()
else:
os.wait()
[...]
So it looks the main() is run 2 times.
Is it so? And if yes, why?


The problem is buffering. When you run your script from the command
line, the standard output is a terminal and becomes line-buffered.
Thus at the time you fork, the stdout buffer has been flushed.

When you run it as a CGI script, stdout is a socket and thus not a
terminal -- so it becomes block buffered. At the time you fork, each
copy of stdout holds all of our unflushed output. When the two
processes exit they will both flush the output, resulting in it being
printed twice.

You can use sys.stdout.flush() to flush the pending output before
forking.

--
================================================== =============
<er***@andreasen.org> Herlev, Denmark
<URL:http://www.andreasen.org/> <*>
================================================== =============

Jul 18 '05 #5
"Andreas Kuntzagk" <an**************@mdc-berlin.de> writes:
So it looks the main() is run 2 times.
Is it so? And if yes, why?
No, it isn't. The problem is that Python uses C STDIO library that has
buffered input and output. The text written in stdout is written in
buffer. Since child process created by fork() is almost identical to
parent process, it will also have a copy of stdout buffer. When
process exits, it closes stdout, which flushes the buffer. So, both
buffers are written to stdout and that causes everything to be printed
twice.

The reason why this doesn happen on command line is that buffers to
terminals are flushed after newline. You can see that by redirecting
script output to file:

$ python script.py >output
$ cat output
Content-Type: text/plain
4309
Content-Type: text/plain
4309
I googled for this but only found a similar question from 1997 and no
answer.


Which is strange since this common problem and has nothing to do with
Python.
--
Juha Autero
http://www.iki.fi/jautero/
Eschew obscurity!
Jul 18 '05 #6
"Andreas Kuntzagk" <an**************@mdc-berlin.de> writes:
def main():
print "Content-Type: text/plain\n\n"
print os.getpid()

childPID = os.fork()
if childPID == 0:
sys.exit()
else:
os.wait()

if __name__ == "__main__":
main()

when run on a shell, gives the result:
---------------------------
Content-Type: text/plain
20953
----------------------------

but run as a cgi-script it gives:
---------------------------
21039
Content-Type: text/plain
21039
---------------------------
So it looks the main() is run 2 times.
Is it so? And if yes, why?


Probably because stdout is being buffered here. The pid got written in the buffer (but not yet actually printed), then the process was forked, then the buffer got flushed (written out) by each child.

One solution would be to make sure everything is flushed before you fork.

Mike

--
Mike Coleman, Scientific Programmer, +1 816 926 4419
Stowers Institute for Biomedical Research
1000 E. 50th St., Kansas City, MO 64110
Jul 18 '05 #7
I googled for this but only found a similar question from 1997 and no
answer.


Which is strange since this common problem and has nothing to do with
Python.


Not so strange, because assuming a Python feature I also included "python"
in the googlequest(tm).

Andreas

Jul 18 '05 #8
On Wed, 02 Jul 2003 09:50:03 +0000, Michael Coleman wrote:
Probably because stdout is being buffered here. The pid got written in
the buffer (but not yet actually printed), then the process was forked,
then the buffer got flushed (written out) by each child.

One solution would be to make sure everything is flushed before you
fork.


Thanx, that's it. Is it possible/advisable to make stdout unbuffered?

Andreas
Jul 18 '05 #9
"Andreas Kuntzagk" <an**************@mdc-berlin.de> writes:
following code: print "Content-Type: text/plain\n\n"
print os.getpid()

childPID = os.fork()
if childPID == 0:
sys.exit()
else:
os.wait()
[...]
So it looks the main() is run 2 times.
Is it so? And if yes, why?


The problem is buffering. When you run your script from the command
line, the standard output is a terminal and becomes line-buffered.
Thus at the time you fork, the stdout buffer has been flushed.

When you run it as a CGI script, stdout is a socket and thus not a
terminal -- so it becomes block buffered. At the time you fork, each
copy of stdout holds all of our unflushed output. When the two
processes exit they will both flush the output, resulting in it being
printed twice.

You can use sys.stdout.flush() to flush the pending output before
forking.

--
================================================== =============
<er***@andreasen.org> Herlev, Denmark
<URL:http://www.andreasen.org/> <*>
================================================== =============

Jul 18 '05 #10
"Andreas Kuntzagk" <an**************@mdc-berlin.de> writes:
So it looks the main() is run 2 times.
Is it so? And if yes, why?
No, it isn't. The problem is that Python uses C STDIO library that has
buffered input and output. The text written in stdout is written in
buffer. Since child process created by fork() is almost identical to
parent process, it will also have a copy of stdout buffer. When
process exits, it closes stdout, which flushes the buffer. So, both
buffers are written to stdout and that causes everything to be printed
twice.

The reason why this doesn happen on command line is that buffers to
terminals are flushed after newline. You can see that by redirecting
script output to file:

$ python script.py >output
$ cat output
Content-Type: text/plain
4309
Content-Type: text/plain
4309
I googled for this but only found a similar question from 1997 and no
answer.


Which is strange since this common problem and has nothing to do with
Python.
--
Juha Autero
http://www.iki.fi/jautero/
Eschew obscurity!
Jul 18 '05 #11
I googled for this but only found a similar question from 1997 and no
answer.


Which is strange since this common problem and has nothing to do with
Python.


Not so strange, because assuming a Python feature I also included "python"
in the googlequest(tm).

Andreas

Jul 18 '05 #12
"Andreas Kuntzagk" <an**************@mdc-berlin.de> writes:
Thanx, that's it. Is it possible/advisable to make stdout unbuffered?


Probably. I'd be more inclined to just do an explicit flush in the
few places where they are specifically needed, though.

Mike

--
Mike Coleman, Scientific Programmer, +1 816 926 4419
Stowers Institute for Biomedical Research
1000 E. 50th St., Kansas City, MO 64110
Jul 18 '05 #13
"Andreas Kuntzagk" <an**************@mdc-berlin.de> writes:
Thanx, that's it. Is it possible/advisable to make stdout unbuffered?


Probably. I'd be more inclined to just do an explicit flush in the
few places where they are specifically needed, though.

Mike

--
Mike Coleman, Scientific Programmer, +1 816 926 4419
Stowers Institute for Biomedical Research
1000 E. 50th St., Kansas City, MO 64110
Jul 18 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Benoit Dejean | last post by:
hello, i have a question about forking processes atm, i have some code which i want to rewrite os.system("cd ~ && exec " + cmd + " & disown") i want to remove this os.system call
7
by: C Gillespie | last post by:
Dear All, I have a function def printHello(): fp = open('file','w') fp.write('hello') fp.close() I would like to call that function using spawn or fork. My questions are:
2
by: CwK | last post by:
How to use fork() system function to fork multi child process at the same time ? For example: Run a program to fork 5 child process at the same time and the parent must wait until all child...
2
by: blah | last post by:
i m using Windows XP, and by tomorrow i will have have fedora core installed too. the problem is, when i use these "fork() and exec()" my windows doesnt do anything, python gives an error about the...
27
by: steve | last post by:
I was given the following code, and asked what the possible outputs could be. We're learning about processes and forking. int value; int main(){ int pid, number = 1; value = 2; pid = fork();...
5
by: mutley | last post by:
for(i=1;i<CONFIG_POLLER_FORKS;i++) { if((pid = fork()) == 0) { server_num=i; break; } else { pids=pid;
1
by: chad.vice | last post by:
I have a CGIC program that generates reporting output on-the-fly. At times this generation can take a long time, and session timeouts occur while users wait for the page results to be displayed. ...
1
by: vduber6er | last post by:
Hi I want to have a wait page while the rest of the cgi does its process, but it seems like the wait page waits till everything is complete and never appears. I've tried forking twice already as...
2
by: Poly-poly man | last post by:
I am working on a GTK Midi player (timidgtk.sourceforge.net). As you can see, it's just a timidity frontend. With version 0.03, I'm trying to devel it to use SDL_sound to play the midis. First...
3
by: anders | last post by:
Hi! I have a problem converting a cgi-program to run on windows. The problem is that the CGI is collecting a lot of information (a orderhandlingsystem) and under unix the main process makes a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.