线程似乎按顺序运行线程

时间:2009-11-08 19:11:07

标签: python multithreading

我正在尝试在我正在处理的Python项目中使用线程,但线程看起来并不像我们的代码中那样。似乎所有线程都是顺序运行的(即线程2在线程1结束后启动,它们不会同时启动)。我写了一个简单的脚本来测试它,并且它也按顺序运行线程。

import threading

def something():
    for i in xrange(10):
        print "Hello"

def my_thing():
    for i in xrange(10):
        print "world"   

threading.Thread(target=something).start()
threading.Thread(target=my_thing).start() 

这是我从运行中获得的输出:

Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
world
world
world
world
world
world
world
world
world
world

在循环迭代次数增加的情况下观察到相同的行为。

我尝试搜索网络和较旧的SO答案,但我找不到任何有用的东西。 有人可以指出这段代码有什么问题吗?

4 个答案:

答案 0 :(得分:14)

目前在python中,线程在执行一些指定数量的字节码指令后会发生变化。它们不会同时运行。当其中一个调用可以释放GIL(全局解释器锁定)的I / O密集型或不受python影响的模块时,您将只有并行执行的线程。

我很确定如果你将循环次数增加到10000次就会使输出混乱。请记住,简单地产生第二个线程也需要“很多”时间。

答案 1 :(得分:11)

在第二个线程启动第一个线程并且已经打印的时间内。

这里看起来像这样,你可以看到第二个线程在第一个线程开始发出几个hellos之后开始。

Hello
Hello
Hello
Hello
Hello
Helloworld

Helloworld

Helloworld

Helloworld

Helloworld

world
world
world
world
world
顺便说一句:你的例子根本没有意义。线程的唯一原因是IO,IO很慢。当您添加一些休眠来模拟IO时,它应该按预期工作:

import threading
from time import sleep

def something():
    for i in xrange(10):
        sleep(0.01)
        print "Hello"

def my_thing():
    for i in xrange(10):
        sleep(0.01)
        print "world"

threading.Thread(target=something).start()
threading.Thread(target=my_thing).start()

出现狂野混音:

worldHello

Helloworld

Helloworld

worldHello

Helloworld

Helloworld

worldHello

Helloworld

worldHello

Helloworld

答案 2 :(得分:4)

行为也可能会发生变化,具体取决于系统使用的是单处理器还是多处理器,如David Beazley的this talk所述。

正如viraptor所说,第一个线程将在执行sys.getcheckinterval()字节码(默认为100)后释放GIL。粗略地总结David Beazley所说的,在单处理器系统上,第二个线程将有机会接管。但是在多核系统上,第二个线程可能在不同的核心上运行,第一个线程将尝试重新获取锁定,并且可能会成功,因为操作系统没有时间切换处理器。这意味着在具有CPU绑定线程的多核系统上,其他线程可能永远不会查看。

这样做的方法是为两个循环添加一个sleep语句,使它们不再受CPU限制。

答案 3 :(得分:3)

这实际上取决于您的操作系统的调度程序,即处理器 除此之外,众所周知,由于GIL(PDF),CPython的线程并不完美,简而言之,这意味着很多时候线程会按顺序运行,或者类似的东西。< / p>