2013-12-22 45 views
2

關卡初學者。我對python中的線程創建方法感到困惑。具體來說有以下兩種方法之間有什麼區別:關於python中的線程混淆

  1. 在第一種方法中,我使用import thread模塊,後來我通過這段代碼thread.start_new_thread(myfunction,())作爲myfunction的創建線程()沒有任何ARGS。

  2. 在第二種方法我使用from threading import Thread,後來我做這樣的事情創建線程:t = Thread(target=myfunction)然後t.start()

爲什麼我問的原因是因爲我的程序工作正常,第二個方法,但當我使用第一種方法時,它不能按預期工作。我正在開發一個客戶端 - 服務器程序。由於

的代碼如下:

#!/usr/bin/env python 

import socket 
from threading import Thread 
import thread 

data = 'default' 
tcpSocket = '' 
def start_server(): 
    global tcpSocket 
    tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    tcpSocket.bind(('',1520)) 
    tcpSocket.listen(3) 
    print "Server is up...." 

def service(): 
    global tcpSocket  
    (clientSocket,address) = tcpSocket.accept() 
    print "Client connected with: ", address 
    # data = 'default' 

    send_data(clientSocket,"Server: This is server\n") 
    global data 
    while len(data): 
     data = receive_data(clientSocket) 
     send_data(clientSocket,"Client: "+data) 

    print "Client exited....\nShutting the server" 
    clientSocket.close() 
    tcpSocket.close() 

def send_data(socket,data): 
    socket.send(data) 
    def receive_data(socket): 
    global data 
    data = socket.recv(2048) 
    return data 


start_server() 

for i in range(2): 
    t = Thread(target=service) 
    t.start() 
#thread.start_new_thread(service,()) 
+0

爲什麼「它不按預期工作」? –

+0

服務器沒有完全啓動。我的意思是socket.accept()之前的代碼工作,但之後程序退出沒有任何錯誤。我可以發佈代碼,但它會使這篇文章太長! –

+0

你當然希望使用更高級別的'threading'模塊,所以如果可行的話,不要擔心更低級別的'thread'。 – shx2

回答

2

@immortal你能解釋一下多一點吧。我沒有感到抱歉。主線程如何死亡?它應該在我的代碼中啓動service(),然後服務器等待客戶端。我想它應該等待而不是死。

你的主線程調用:

start_server() 

和回報。然後你的主線程執行這個:

for i in range(2): 
    t = Thread(target=service) 
    t.start() 
#thread.start_new_thread(service,()) 

那些也幾乎立即完成,然後你的主線程結束。

此時,主線程爲完成。 Python輸入其解釋器關閉代碼。

部分關機代碼是正在等待.join()threading模塊創建的所有(非守護程序)線程。這是它的更好的原因之一不是要使用thread,除非你確切地知道你在做什麼。例如,如果你是我;-)但我唯一使用thread的地方在實現threading,並編寫thread模塊的測試代碼。

你完全依靠自己來管理thread模塊線程的所有方面。 Python的關閉代碼不會等待這些線程。解釋器只是退出,完全忽略它們,操作系統將它們關閉(嗯,這真的取決於操作系統,但是在我知道的操作系統的所有主流平臺上,它們都會在中途不正常地殺死它們)。

+0

感謝您的解釋。我應該在某處使用setDaemon(True)嗎?但我不知道在哪裏。這對我來說是一個有趣的概念,但也有點複雜。 –

+0

建議不要使用守護進程線程,除非你確切知道你在做什麼。努力乾淨地關閉你的線程 - 將線程對象保存在列表中,並顯式地''.join()'自己。你在開始時不需要*更多*魔法,你需要*少* ;-)「顯式比隱式更好」 –