2017-08-28 12 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で2回起動します。

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とは1行だけです。
run.pyを2回起動してください。

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を2回起動します。 JohanLとして

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)> 

は言う:最初に実行されるためにどのよう
二つの別々のスレッドを実行し、すべてのベットはオフになっています。
基本的にスケジューリングをオペレーティングシステムに委ねています。 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 

カンマを付けずに1つのprint文を使用してみてくださいそれがどうあるべきかを理解する:

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

これは正常に動作しますが、2つの機能を同時に印刷されているので、次のような出力を得るかもしれません:これが機能することを証明するために

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

をあなたはtime.sleep()を使用して、2回の呼び出しの間の遅延を使用することができます。

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() 

今、あなたは、各機能が1ティムを印刷しているので、あなたがあなたの所望の出力を得ることがわかります呼び出しの間で0.1秒遅れでE:

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

EDIT:あなたの代わりに二度同じスレッドを実行しているのをマルチスレッドを使用する必要があります正確な理由

あなたの問題があります。 マルチスレッドを使用する場合thread.join()を使用すると、スレッドが終了してからコードを続行するか、threading.lock()を使用してコードを続行できますが、一度に1つのスレッドで使用する関数をロックできます。ここでいくつかの例は、次のとおり

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の問題です)。あなたが記述した1行の場合のすべて(行送りが別々にstdoutストリームに書き込まれることを意味する) – MacHala

+0

@MacHala 2つのスレッドが印刷しているが、ここでは2つの関数を実行する1つのスレッドと両方の関数が印刷している –

0

どのバージョンのpython WERあなたは使っていますか? Python 2では、 "print"はスレッドセーフではありません。 http://tech.queryhome.com/54593/is-print-thread-safe-in-python-2-6-2-7をご覧ください。

"print"中にスレッドが切り替わると、出力は見たように混ざります。

+1

Python 2の構文は明らかです。そして、それは「スレッドセーフ」が意味するものではありません。 – pvg

+0

@pvg、 "スレッドセーフ"の意味は? – VHao

+1

VHaoが正しいです。文脈がより多くの議論を書いている間に切り替えられて予期せぬ結果となることがありますが、これはスレッドセーフではないとよく言えるかもしれません。 – 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を使用することを強くお勧めします。

関連する問題