2017-08-28 114 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