python-ThreadPoolExecutor为什么线程池中的任务会按顺序执行

huangapple go评论65阅读模式
英文:

python-ThreadPoolExecutor why task in threadpool will be execute in sequence

问题

def m1():
    for i in range(1,10):
        print("m1 i=" + str(i) + " \n")
        time.sleep(0.5)

def m2():
    for i in range(1, 10):
        print("m2 i=" + str(i) + " \n")
        time.sleep(0.5)

def m3():
    for i in range(1,10):
        print("m3 i=" + str(i) + " \n")
        time.sleep(0.5)

with ThreadPoolExecutor(max_workers=2) as tp:
    tp.submit(m1)
    tp.submit(m2)
    tp.submit(m3)

结果:

m1 i=1 

m2 i=1 

m1 i=2 

m2 i=2 

m1 i=3 

m2 i=3 

m1 i=4 

m2 i=4 

m1 i=5 

m2 i=5 

m1 i=6 

m2 i=6 

m1 i=7 

m2 i=7 

m1 i=8 

m2 i=8 

m1 i=9 

m2 i=9 

m3 i=1 

m3 i=2 

m3 i=3 

m3 i=4 

m3 i=5 

m3 i=6 

m3 i=7 

m3 i=8 

m3 i=9 

对我困惑的是,虽然我使用了 time.sleep(),但线程没有挂起。所有任务按照提交的顺序执行。为什么会这样?

英文:
def m1():
    for i in range(1,10):
        print("m1 i="+str(i)+" \n")
        time.sleep(0.5)

def m2():
    for i in range(1, 10):
        print("m2 i=" + str(i)+" \n")
        time.sleep(0.5)
def m3():
    for i in range(1,10):
        print("m3 i="+str(i)+" \n")
        time.sleep(0.5)
with ThreadPoolExecutor(max_workers=2) as tp:
    tp.submit(m1())
    tp.submit(m2())
    tp.submit(m3())

I made a threadpool and submitted 3 tasks

Result:

m1 i=1 

m1 i=2 

m2 i=1 

m2 i=2 

m3 i=1 

m3 i=2 

What confused me is that, although I use time.sleep(), the thread is not hang up. All tasks are executed by submit sequence.
Why is that ?

答案1

得分: 1

你需要将一个函数传递给线程池,而不调用它:

with ThreadPoolExecutor(max_workers=2) as tp:
    tp.submit(m1)
    tp.submit(m2)
    tp.submit(m3)

在你的情况下,它们会立即执行,因此它们的执行是顺序的。

英文:

You need to pass a function to the threadpool, without calling it:

with ThreadPoolExecutor(max_workers=2) as tp:
    tp.submit(m1)
    tp.submit(m2)
    tp.submit(m3)

In your case they get executed "on the spot" hence why their execution is sequential.

答案2

得分: 0

答案由@Learningisamess提供是正确的,但我认为你应该更详细地了解它。

这是一个函数调用:

m1()

你可能已经知道这一点。但也许你不知道的是,每个函数调用都是一个_表达式.也就是说,它是一段可以被_求值_的代码片段(即,它可以被_执行_以产生一个_值)。

下面是另一个表达式:

a+3

它由两个_子表达式_组成,即a3。它通过首先求值其子表达式,然后将这两个值相加来进行求值。a通过从名为“a”的变量中获取值来进行求值,而3则很简单——它的值始终为3。

函数调用表达式中的参数也是子表达式。因此,tp.submit(x)首先求值x,然后将该值传递给tp.submit函数。*

你写道:

tp.submit(m1())

这将首先通过调用m1函数来求值子表达式m1()。立即执行。在程序的主线程中。无论m1()返回什么都成为子表达式的值。然后最终,tp.submit将使用m1()返回的任何内容进行调用。

m1()返回None。而tp.submit(None)基本上什么都不做。特别是它不会生成任何错误。它基本上被忽略了。

你真正想要做的是@Learningisamess所说的:写tp.submit(m1)而不是tp.submit(m1())m1是一个其值为函数本身的表达式,tp.submit(m1)告诉线程池稍后在不同的线程中调用该函数。


* 实际上,tptp.submit也是tp.submit(x)的子表达式,但我不打算深入探讨_那个_兔子洞的底部。

英文:

The answer by @Learningisamess is correct, but I think you should hear it in more detail.

This is a function call:

m1()

You probably already knew that. But maybe what you did not already know is that every function call is an expression. That is, a fragment of code that can be evaluated (i.e., it can be executed to yield a value.)

Here's another expression:

a+3

It is composed of two sub-expressions, a and 3. It is evaluated by first evaluating its sub-expressions, and then adding the two values together. The a is evaluated by fetching the value from a variable named "a," and the 3 is trivial--its value always is 3.

The arguments in a function call expression are sub-expressions too. So, tp.submit(x) first evaluates x, and then it passes that value to the tp.submit function.*

You wrote:

tp.submit(m1())

That will first evaluate the subexpression, m1() by calling the m1 function. Immediately. In the program's main thread. Whatever m1() returns becomes the value of the subexpression. Then finally, tp.submit will be called with whatever m1() returned.

m1() returns None. And tp.submit(None) essentially does nothing. In particular, it does not generate any kind of error. It's pretty much just ignored.

What you really wanted to do is what @Learningisamess said: Write tp.submit(m1) instead. m1 is an expression whose value is the function itself, and tp.submit(m1) tells the thread pool to call that function some time later, and in a different thread.


* In fact, tp, and tp.submit also are sub-expressions of tp.submit(x), but I'm not going to dive all the way to the bottom of that rabbit hole.

huangapple
  • 本文由 发表于 2023年7月3日 18:37:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76603943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定