简体   繁体   English

多线程不像我期望的那样工作

[英]Multithreading doesn't work like I expect it to

I'm learning threading in Python 3. 我正在学习Python 3中的线程。

This is a simple concept example. 这是一个简单的概念示例。 I want each thread to wait for 5 seconds before it prints, so the call to the thread is only 1 second large, it must return to the main thread. 我希望每个线程在打印之前都要等待5秒钟,因此对该线程的调用只有1秒大,它必须返回到主线程。

But the output for my code isn't what I expect. 但是我的代码输出不是我期望的。

My code: 我的代码:

import threading, time

class MyThread(threading.Thread):  
    def __init__(self, num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self): 
        time.sleep(5)
        print ("I'm thread number: ", self.num)


print ("I'm the principal thread.")

for i in range(0, 10):
    t = MyThread(i)  
    t.start()      
    t.join(1)     
    print("I'm the principal thread, too.")

The output: 输出:

I'm the principal thread.
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm thread number:  0
I'm the principal thread, too.
I'm thread number:  1
I'm the principal thread, too.
I'm thread number:  2
I'm the principal thread, too.
I'm thread number:  3
I'm the principal thread, too.
I'm thread number:  4
I'm the principal thread, too.
I'm thread number:  5
I'm the principal thread, too.
I'm thread number:  6
I'm thread number:  7
I'm thread number:  8
I'm thread number:  9

The expected output is something like this: 预期的输出是这样的:

I'm the principal thread.
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm thread number:  0
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm thread number:  1
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm thread number:  2
I'm the principal thread, too.
... 

What am I doing wrong? 我究竟做错了什么?

It sounds like you want the principal thread to keep printing once per second until the other thread finishes. 听起来您希望主线程每秒继续打印一次,直到另一线程完成。 But this won't happen, since the principal thread will give up and move to the next thread after attempting to join once. 但这不会发生,因为在尝试join一次后,主线程将放弃并移至下一个线程。 You ought to keep join ing until the thread finishes. 您应该继续join直到线程完成。

import threading, time

class MyThread(threading.Thread):  
    def __init__(self, num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self): 
        time.sleep(5)
        print ("I'm thread number: ", self.num)


print ("I'm the principal thread.")

for i in range(0, 10):
    t = MyThread(i)  
    t.start()      
    while True:
        t.join(1)
        print("I'm the principal thread, too.")
        if not t.isAlive(): break

Based on your output, I think below logic must work 根据您的输出,我认为以下逻辑必须有效


import threading, time

class MyThread(threading.Thread):  
    def __init__(self, num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self): 
        time.sleep(5)
        print ("I'm thread number: ", self.num)


print ("I'm the principal thread.")

for i in range(0, 10):
    t = MyThread(i)  
    t.start()      
    t.join(1)
    ## You join Times out here, since the thread didnt finish in 1 sec 
    ##(its sleeping for 5 secs)
    while t.isAlive():
        time.sleep(1)
        print("I'm the principal thread, too.")

There is a time lag of one second in your for loop. for循环中存在一秒的时间延迟。 So, before the spawned thread waits for 5 seconds, the "I'm the principal thread, too." 因此,在生成的线程等待5秒钟之前,“我也是主线程”。 gets printed 4 times. 被打印4次。 By then, the thread with num=0 has completed waiting for 5 sec. 到那时,num = 0的线程已经完成等待5秒钟。 and so it prints. 这样就可以打印了。

for i in range(0, 10):
    t = MyThread(i)  
    t.start()      
    t.join(1)     
    print("I'm the principal thread, too.")

In this block, notice the t.join(1) . 在此块中,注意t.join(1) It waits for 1 sec. 等待1秒。 for the thread 't' to complete, but since the thread is actually waiting for 5 sec. 等待线程“ t”完成,但是由于线程实际上正在等待5秒。 after getting started, it goes ahead with the loop. 在开始之后,它将继续循环。 Thus, 从而,

I'm thread number:  0
I'm the principal thread, too.
I'm thread number:  1

this points to the time.sleep(1) . 这指向time.sleep(1) The thread number 1 is spawned after 1 sec. 1秒后生成线程号1。 the thread number 0 was spawned, and so forth. 产生了线程号0,依此类推。

The loop runs only 10 times, and thus the "I'm the principal thread, too." 该循环仅运行10次,因此“我也是主线程”。 prints only 10 times. 仅打印10次。

I'm the principal thread.
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm the principal thread, too.
I'm thread number:  0
I'm the principal thread, too.
I'm thread number:  1
I'm the principal thread, too.
I'm thread number:  2
I'm the principal thread, too.
I'm thread number:  3
I'm the principal thread, too.
I'm thread number:  4
I'm the principal thread, too.
I'm thread number:  5
I'm the principal thread, too.

By this time, the loop is over, but the remaining threads are still waiting to print out after waiting for their 5 sec., and thus you see the: 到这个时候,循环结束了,但是其余线程在等待5秒钟之后仍在等待打印,因此您将看到:

I'm thread number:  6
I'm thread number:  7
I'm thread number:  8
I'm thread number:  9

The problem with the discrepancy in the output is that each thread that is spawned waits for 5 secs. 输出差异的问题是,产生的每个线程都等待5秒。 while you call join on it only for a second. 而您只需要加入一秒钟即可加入。 Thus, no thread will finish in the allotted 1 sec. 因此,没有线程会在分配的1秒内完成。 If you want to truly wait for the thread generated to complete, you should do this: 如果要真正等待生成的线程完成,则应执行以下操作:

for i in range(0, 10):
    t = MyThread(i)  
    if t.is_alive():
        t.join()    
    print("I'm the principal thread, too.")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM