fork有一些***,其中最明顯的就是重複的檔案描述符。比如,socket, 磁碟上的檔案,終端(標準輸入、輸出,錯誤)或某些其他檔案類物件。
因為乙個程序的fork是乙個準確的拷貝,它繼承了父程序的所有檔案描述符和socket,所以就可能遇到這樣乙個情況,那就是父程序和子程序對於乙個單一的遠端主機,都有乙個開放的連線.
這並不好,有幾個原因,如果兩個程序都檢視通過socket通訊,結果就可能混淆。另外一點是,兩個程序都要呼叫 close() ,連線才能真正被關閉。因此,一些協議中,使用關閉socket作為某些操作結束訊號的情況會出現問題。除非父程序和子程序都關閉了。
這個問題的解決辦法是在fork之後,只要程序不用 socket的時候就馬上關閉它。
#!/usr/bin/env python
#!coding=utf-8
forking 伺服器
多程序伺服器
import socket ,traceback, os,sys
import time
def reap():
print "in reap"
處理子程序
while 1:
try:
print "in reap ,pid=%s"%(getpid())
result = os.waitpid(-1 , os.wnohang) # -1 表示等待所有的子程序結束,作用相當於呼叫wait ,wnohang表示不使父程序掛起,而立即返回
print "000000000000000"
if not result[0]:
break
except:
break
print "reaped child process %d" % result[0]
def getpid():
return os.getpid()
host=''
port=9002
s =socket.socket(socket.af_inet, socket.sock_stream)
s.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1)
s.bind((host, port))
s.listen(1)
print "parent at %d listening for connection" % getpid()
if __name__ == "__main__":
while 1:
try:
print "accept , pid= %s"%(getpid())
clientsock , clientaddr = s.accept()
print "start accpet"
except keyboardinterrupt:
raise
except:
traceback.print_exc()
continue
#reap()
pid = os.fork()
print "*****************"
if pid:
#子父程序中
#this is the parent process .close the child's socket
print "in parent socket"+str(clientsock)
print "in parent port=%s"%str(port)
print "in parent s=%s"%str(s)
"""
這裡為什麼要關閉clientsock呢,這裡解釋(this is the parent process .close the child's socket)
關閉的是子執行緒的socket,我覺得是寫錯了,
應該關閉的是父程序的client的socket連線,因為這裡是在父程序裡面,這裡為什麼要關閉呢,
因為多程序是, 子程序會複製父程序的資料,那麼這樣clientsocket,就會存在2次飲用(父程序乙個,
子程序乙個) ,如果每建立一次子程序都增加一次引用的話,這樣就會消耗系統的資源,所以這裡應該關閉
"""clientsock.close()
#s.close()
print "in parent socket"+str(clientsock)
continue
else:
#在子程序中
#from here on . this is child
#clientsock.close()
print "in child socket"+str(clientsock)
print "in child port=%s"%str(port)
print "in child s=%s"%str(s)
"""
子程序裡面也有s, 父程序也有s,如果這時候,客戶端有連線的話,就有可能出現混亂的情況,所以這裡選擇關閉
子程序的s
"""s.close()
#process the connection
try:
print "child from %s being handled bu pid %d"%\
(clientsock.getpeername(), os.getpid())
#不停的迴圈接收資料
while 1:
data = clientsock.recv(4096)
print str(data) + " , pid = %s"%(getpid())
if not len(data):
break
clientsock.sendall(data)
except(keyboardinterrupt, systemexit):
raise
except:
traceback.print_exc()
#close the connection
try:
print "斷開連線 ,pid=%s"%(getpid())
clientsock.close()
except keyboardinterrupt:
raise
except:
traceback.print_exc()
print "程序結束,pid=%s"%(getpid())
sys.exit(0)
linux 多程序 缺點
fork有一些 其中最明顯的就是重複的檔案描述符。比如,socket,磁碟上的檔案,終端 標準輸入 輸出,錯誤 或某些其他檔案類物件。因為乙個程序的fork是乙個準確的拷貝,它繼承了父程序的所有檔案描述符和socket,所以就可能遇到這樣乙個情況,那就是父程序和子程序對於乙個單一的遠端主機,都有乙個...
程序 執行緒 多程序 多執行緒的優缺點
ibm有個傢伙做了個測試,發現切換執行緒context的時候,windows比linux快一倍多。進出最快的鎖 windows2k的 critical section和linux的pthread mutex windows比linux的要快五倍左右。當然這並不是說linux不好,而且在經過實際程式設...
linux多程序程式設計
在linux中,執行的乙個程序,會占去linux的三個地方,區,堆疊區和資料區.如果同時執行多個相同的程式,他們就會使用相同的 區,區中存放的就程式的 但是資料區和堆疊區分別存放的是程式的資料,全域性變數和區域性變數,因此即使是相同的程式,也不可同時使用相同的資料和堆疊區.include inclu...