【问题标题】:Thread and init at the same time (how it works?)同时线程和初始化(它是如何工作的?)
【发布时间】:2018-11-07 20:55:39
【问题描述】:

我最近开始研究线程,我知道这是关于多个处理的东西我只是不明白为什么会发生这种情况

import threading

class BuckyMessenger(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        print("test")

    def run(self):
        for _ in range(4):
            print(threading.current_thread().getName())

    x = BuckyMessenger(name='Send')
y = BuckyMessenger(name='Receive')
z = BuckyMessenger(name='Nothing')
x.start()
y.start()
z.start()

我预计会发生这种情况:

test
Send
test
Receive
test
Nothing

从这里开始,我应该再打印 9 个打印件,分别是 3 个随机“发送”、3 个随机“接收”和 3 个随机“无”,如下所示:(其余结果)

Send
Receive 
Nothing 
Nothing
Nothing
Send
Receive 
Receive 
send

但这是我得到的结果: 我是说为什么?为什么python会这样?

test
test
test
Thread-1
Thread-1
Thread-1
Thread-1
Thread-2
Thread-2
Thread-2
Thread-2
Thread-3
Thread-3
Thread-3
Thread-3

【问题讨论】:

  • 可能是因为初始化线程的时间与打印输出的时间一样长

标签: python multithreading constructor thread-safety python-multithreading


【解决方案1】:

您需要获取对当前正在运行的线程的引用并设置其名称。然后您可以使用该引用来打印其名称。注意构造函数和run 方法的变化。至于串行执行的效果,是因为每个线程能够足够快地执行并在另一个发生之前完成,因为循环周期很少:

import threading

class BuckyMessenger(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name
        print("test")

    def run(self):
        curThread = threading.current_thread()
        curThread.name = self.name
        for _ in range(4):
            print(curThread.name)

x = BuckyMessenger(name='Send')
y = BuckyMessenger(name='Receive')
z = BuckyMessenger(name='Nothing')
x.start()
y.start()
z.start()

可能的输出:

test
test
test
Send
Send
Send
Send
Receive
Nothing
Nothing
Receive
Nothing
Nothing
Receive
Receive

【讨论】:

  • test test test Send Send Send Send Receive Receive Receive Receive Nothing Nothing Nothing 每次都是这样的结果,是线程吗?因为我没有混合“接收”、“无”和“发送”
  • 这是因为 CPU 能够足够快地执行每个线程,所以看起来像串行执行。您可以做的一件事是增加循环周期的数量,另一件事是强制每个线程暂停随机生成的时间量,例如time.sleep(random.random())。确保为后一个选项导入 timerandom 模块。将time.sleep(random.random()) 放在for 循环中,在print 语句之前。
【解决方案2】:

您的初始化程序没有将传递的name 设置为BuckyMessanger。这是因为您覆盖了原始的 Thread.__init__(),它按照您的预期处理 name。线程的默认名称是 Thread-1 等等,按照它们各自的创建顺序。将您的初始化程序更改为以下内容以覆盖默认值:

def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name
        print("test")

至于为什么它们按此顺序打印,BuckyMessanger.run() 在每个 start() 之后运行,并在下一个 start() 被调用之前完成。

【讨论】:

    猜你喜欢
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    相关资源
    最近更新 更多