1

i am trying to code socket server with fork in python. somehow a new fork will be created when a client is connected and this fork process will handle the connection including send/receive.
i ran this script on Linux centOS and monitor resources with htop/top to see how many forks (task) are shown. the problem is when i kill some fork by using os._exit(0) htop won't be changed (naturally it has to be decreased by killing forks) and when i close python script every thing will be back to normal ( Ram usage and tasks ).
so what i have to do that when i kill some fork by using os._exit(0), it effects on htop in other hand releases all resources and do not wait until its own parent is killed ?

here it's the code to create forks:

def test(sock):
     //handle socket then return
for i in range (1000):
     sock,addr=socket.accept()
     pid=os.fork()
     if pid==0:
          test(sock)
          os._exit(0)
     elif pid !=-1:
          os.waitpid(-1, os.WNOHANG)
Mehrdad Dadvand
  • 340
  • 4
  • 19

1 Answers1

3

The parent process needs to wait for the child in order for the child process' resources to be released. Until then the process still exists in a "zombie" state, and it will still appear in ps and top etc.

You can call one of os.wait(), os.waitpid(), os.wait3(), or os.wait4().

os.wait3() with the os.WNOHANG option might be most useful to you as it will wait for any child process and the parent will not block until a child terminates (or it's state changes - wait will return child processes that have been stopped or restarted too).

More details on the underlying system calls can be found in the Linux man page: man 2 wait.

mhawke
  • 84,695
  • 9
  • 117
  • 138
  • i used `os.waitpid(childPID,0)` in parent . but the parent does not accept any more connection until the child process done and exits.but i need when i use `os._exit(0)` in fork process it disapear in ps or top . in other hand release all resources . but now if i create 1000 forks and even destroy them all ( `os._exit(0)` ) it seems `top or ps` still shows tasks=1000. it seems fork have not been clean or something like that. but when i terminate python process and stop every it then every thing gonna be ok – Mehrdad Dadvand Feb 18 '16 at 12:15
  • @MehrdadDadvand: the parent will not accept any more connections because it is blocked waiting for the child to terminate. You can run `os.waitpid(childPID,os.WNOHANG)` and the parent will not block, and will return `(0, return_code)` indicating that the child terminated, or (childPID, return_code) if it didn't. I mentioned `os.wait3(os.WNOHANG)` in my answer, which is almost the same as `os.waitpid(-1, os.WNOHANG), but it returns extra resource info about the child which might be useful to log in your parent process. – mhawke Feb 18 '16 at 12:43
  • i think still there is small problem here . i used `os.waitpid(-1,os.WNOHANG)` and `tasks` in top is not going to update with fork termination . but it is not going to increase like Previous code. – Mehrdad Dadvand Feb 18 '16 at 14:03
  • i can see a lot of task zombie field in `top` when i run my scripy. i think task are still in zombie state – Mehrdad Dadvand Feb 18 '16 at 14:12
  • It's difficult to comment without seeing the code in question. Are you calling `os.waitpid()` many times? What is it returning? - is it actually returning the PID of a terminated child, or 0 (in which case it didn't join with any child).? Perhaps you could add to your questinon a minimal working example of your code. – mhawke Feb 18 '16 at 14:46