python 线程似乎按顺序运行线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1697571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:52:53  来源:igfitidea点击:

threading appears to run threads sequentially

pythonmultithreading

提问by MAK

I am trying to use threads in a Python project I am working on, but threads don't appear to be behaving as they are supposed to in my code. It seems that all threads run sequentially (i.e. thread2 starts after thread 1 ends, they don't both start at the same time). I wrote a simple script to test this, and that too runs threads sequentially.

我正在尝试在我正在处理的 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() 

Here's the output I get from running it:

这是我运行它的输出:

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

The same behavior is observed with much larger number of iterations of the loops.

在循环的大量迭代中观察到相同的行为。

I tried searching the web and older SO answers, but I couldn't find anything that helped. Can someone please point out what is wrong with this code?

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

回答by viraptor

Currently in python, threads get changed after executing some specified amount of bytecode instructions. They don't run at the same time. You will only have threads executing in parallel when one of them calls some I/O-intensive or not python-affecting module that can release GIL (global interpreter lock).

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

I'm pretty sure you will get the output mixed up if you bump the number of loops to something like 10000. Remember that simply spawning the second thread also takes "a lot" of time.

我敢肯定,如果您将循环次数增加到 10000 之类的值,您会混淆输出。请记住,简单地生成第二个线程也需要“很多”时间。

回答by Jochen Ritzel

In the time it takes the second thread to start the first thread loops and prints already.

在第二个线程开始第一个线程循环并打印所需的时间内。

Here it looks like this, you can see the 2nd thread starting after the first emitted a few hellos.

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

Hello
Hello
Hello
Hello
Hello
Helloworld

Helloworld

Helloworld

Helloworld

Helloworld

world
world
world
world
world

Btw: Your example is not meaningful at all. The only reason for Threads is IO, and IO is slow. When you add some sleeping to simulate IO it should work as expected:

顺便说一句:你的例子根本没有意义。Threads的唯一原因就是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()

a wild mix appears:

一个狂野的组合出现:

worldHello

Helloworld

Helloworld

worldHello

Helloworld

Helloworld

worldHello

Helloworld

worldHello

Helloworld

回答by Dave Kirby

The behaviour may also change depending on if the system is using has a single processor or multiple processors, as explained by this talkby David Beazley.

根据系统使用的是单个处理器还是多个处理器,行为也可能会发生变化,正如David Beazley 的演讲所解释的那样。

As viraptor says, the first thread will release the GIL after executing sys.getcheckinterval() bytecodes (100 by default). To crudly summarise what David Beazley says, on a single processor system the second thread will then have a chance to take over. However on a multi-core system the second thread may be running on a different core, and the first thread will try to reacquire the lock and will probably succeed since the OS will not have had time to switch processors. This means that on a multi-core system with a CPU-bound thread the other threads may never get a look in.

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

The way round this is to add a sleep statement to both of the loops so that they are no longer CPU bound.

解决这个问题的方法是在两个循环中添加一个 sleep 语句,以便它们不再受 CPU 限制。

回答by abyx

This really depends on your Operating System's scheduler, your processor.
Other than that, it is known that CPython's threads aren't perfect because of the GIL(PDF), which, in short, means that a lot of the times threads do run sequentially, or something of that sort.

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