2017-08-28 55 views
12

start.py代碼如下。相同的程序不同的線程輸出模塊

import threading 
class myThread(threading.Thread): 
     def __init__(self, threadID, name): 
       threading.Thread.__init__(self) 
       self.threadID = threadID 
       self.name = name 

     def run(self): 
       currentThreadname = threading.currentThread() 
       print "running in ", currentThreadname 

thread = myThread(1,"mythrd") 
thread.start() 

用python啓動它兩次。

python start.py 
running in <myThread(mythrd, started 140461133485824)> 
python start.py 
running in <myThread(mythrd, started 140122860668672)> 

run.py代碼如下。

import threading 
class myThread(threading.Thread): 
     def __init__(self, threadID, name): 
       threading.Thread.__init__(self) 
       self.threadID = threadID 
       self.name = name 

     def run(self): 
       currentThreadname = threading.currentThread() 
       print "running in ", currentThreadname 

thread = myThread(1,"mythrd") 
thread.run() 

run.py只有一行不同於start.py。
現在啓動兩次run.py。

python run.py 
running in <_MainThread(MainThread, started 139854546364160)> 
python run.py 
running in <_MainThread(MainThread, started 139854546364160)> 

startandrun.py代碼如下。

class myThread(threading.Thread): 
    def __init__(self, threadID, name): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 

    def run(self): 
     currentThreadname = threading.currentThread() 
     print "running in ", currentThreadname 

thread = myThread(1,"mythrd") 
thread.start() 
thread.run() 

現在啓動兩次startandrun.py。

python startandrun.py 
running in <myThread(mythrd, started 140317119899392)> 
running in <_MainThread(MainThread, started 140317144454912)> 
python startandrun.py 
running in running in <_MainThread(MainThread, started 139980210505472)> 
<myThread(mythrd, started 139980185949952)> 

由於JohanL說:
當運行兩個獨立的線程,所有的賭注都關閉哪個會首先執行。
您基本上將調度離開到操作系統。 第一次執行startandrun.py,thread.start()thread.run()之前被執行,它導致輸出:

running in <myThread(mythrd, started 140317119899392)> 
running in <_MainThread(MainThread, started 140317144454912)> 

第二時間來執行startandrun.py,thread.start()thread.run()之後被執行,爲什麼不導致輸出:

running in <_MainThread(MainThread, started 140317144454912)> 
running in <myThread(mythrd, started 140317119899392)> 

,而不是

running in running in <_MainThread(MainThread, started 139980210505472)> 
<myThread(mythrd, started 139980185949952)> 
+1

當運行兩個獨立的線程中,所有的賭注都關閉,以它將首先執行。您基本上將時間安排交給操作系統。這就是爲什麼當你的線程訪問相同的數據時你需要不同的同步原語(信號量,監視器等)。 – JohanL

+0

'thread.run'不會啓動一個新線程,所以這段代碼可能不會做你認爲正在做的事。要開始一個線程,你需要調用'start'。你不應該直接調用'run','start'會爲你做。調用開始和運行只是爲了進一步混淆你試圖理解的任何問題。請參閱文檔,對此非常清楚:「創建線程對象後,必須通過調用線程的start()方法來啓動它的活動,然後在單獨的控制線程中調用run()方法。」 – pvg

回答

4

發生這種情況,因爲你現在的樣子打印值:

print "running in ", currentThreadname 

添加逗號是類似於:

print 'running in ' # without new line at the end 
print currentThreadname 

而且因爲這兩個功能在同一時間跑這裏訂單是如何執行的:

print 'running in ' # without new line FUNCTION #1 
print 'running in ' # without new line FUNCTION #2 
print currentThreadName # with new line at the end FUNCTION #1 
print currentThreadName # with new line at the end FUNCTION #2 

嘗試使用一個沒有逗號的打印語句來了解應該如何:

def run(self): 
    currentThreadname = threading.currentThread() 
    print "running in {}".format(currentThreadname) 

這將表現正常,但由於這兩個功能在同一時間打印時,您可能會遇到以下的輸出:

running in <myThread(mythrd, started 10716)>running in <_MainThread(MainThread, started 12132)> 

所以證明,這將工作您可以使用time.sleep()中使用的延遲在兩個電話之間:

import threading 
import time 

class myThread(threading.Thread): 
    def __init__(self, threadID, name): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 

    def run(self): 
     currentThreadname = threading.currentThread() 
     print "running in {}".format(currentThreadname) 

thread = myThread(1,"mythrd") 
thread.start() 
time.sleep(0.1) 
thread.run() 

現在你可以看到你得到你想要的輸出,因爲每一個功能是打印一個添e爲在呼叫之間0.1秒的延遲:

running in <myThread(mythrd, started 5600)> 
running in <_MainThread(MainThread, started 7716)> 

編輯:

你的問題就是爲什麼你應該使用多線程代替運行在同一個線程兩次。當您使用多線程您可以使用thread.join()這將等待線程完成關閉,然後繼續代碼,或者您可以使用threading.lock(),所以你可以繼續你的代碼,但鎖定功能,可以由一個線程在同一時間使用。下面是一些例子:

的Thread.join()

thread = myThread(1, "mythrd") 
thread2 = myThread(2, "thrd2") 
thread.start() 
thread.join() # code will stop here and wait for thread to finish then continue 
thread2.run() 

threading.lock()

.... 
    def run(self): 
     with lock: # if one thread uses this lock the other threads have to wait 
      currentThreadname = threading.currentThread() 
      print "running in ", currentThreadname 

thread = myThread(1, "mythrd") 
thread2 = myThread(2, "thrd2") 
lock = threading.Lock() 
thread.start() 
thread2.run() 
# code keeps running even if there are threads waiting for the lock 
+0

我同意開始(也許這是OP的問題),儘管我不認爲它有可能得到在一行的情況下,你描述的一切(這將意味着換行符分開寫入標準輸出流) – MacHala

+0

@MacHala它是不可能的,如果兩個線程正在打印,但在這裏它的一個線程運行兩個功能,並且這兩個功能正在打印 –

0

Python版本WER你在用嗎?在python 2中,「print」不是線程安全的。請參閱http://tech.queryhome.com/54593/is-print-thread-safe-in-python-2-6-2-7

如果在「打印」過程中線程切換,輸出會混合,就像您看到的一樣。

+1

給出語法顯然是python 2。這不是'線程安全'的含義。 – pvg

+0

@pvg,那麼「線程安全」的含義是什麼? – VHao

+1

VHao是對的;上下文可能在寫入更多參數期間切換,導致意外的輸出,這可以很好地描述爲imho不是線程安全的 – MacHala

2

所以,你只需要同步你的線程。可以使用線程庫中的join()函數輕鬆完成。

你可以做這樣的事情

class myThread(threading.Thread): 
    def __init__(self, threadID, name): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 

    def run(self): 
     currentThreadname = threading.currentThread() 
     print "running in ", currentThreadname 

thread = myThread(1,"mythrd") 
t1 = thread.start() 
t1.join() 
t2 = thread.run() 
t2.join() 

您還可以使用信號量和鎖了更好的理由。有關更多詳細信息,請參閱文檔。

2

也許你不明白線程是如何工作的。 仔細閱讀this

我強烈建議您使用futures庫中的ThreadPoolExecutor

相關問題