2个并行运行的线程的奇怪输出

问题描述 投票:1回答:1

我的代码。它从内部调度程序开始2个线程,这些调度程序每秒打印一次数字

import threading
import time
from datetime import datetime

import schedule

_lock = threading.Lock()


def p(number):
    _lock.acquire()
    print(number, datetime.now())
    _lock.release()


def f(number):
    schedule.every(5).seconds.do(p, number)
    while True:
        schedule.run_pending()
        time.sleep(1)


thread = threading.Thread(target=f, args=(1,))
thread2 = threading.Thread(target=f, args=(2,))
thread.start()
thread2.start()

预期输出

1 2020-03-25 22:07:17.817528
2 2020-03-25 22:07:17.817528
1 2020-03-25 22:07:22.821887
2 2020-03-25 22:07:22.821887
1 2020-03-25 22:07:27.826093
2 2020-03-25 22:07:27.826093

实际输出(请参阅在17'处代替4个打印件,在27'处代替2个打印件)

1 2020-03-25 22:07:17.817528
2 2020-03-25 22:07:17.817528
1 2020-03-25 22:07:17.817528
2 2020-03-25 22:07:17.817528
1 2020-03-25 22:07:22.821887
2 2020-03-25 22:07:22.821887
1 2020-03-25 22:07:27.826093
2 2020-03-25 22:07:27.826093
2 2020-03-25 22:07:27.826093

我实际上不知道为什么有时线程触发器的功能不止一次。知道我做错了什么吗?

python python-multithreading schedule
1个回答
2
投票

您正在使用所谓的race condition。两个线程正试图同时写入stdout(即print),但是它们能够获得此资源的顺序取决于调度程序的时间。

为了解决该问题,您需要引入一种同步其访问的方法,因此当一个线程尝试打印某些内容时,另一个线程必须等到完成为止。

像这样修改您的代码:

import threading
# ...

_lock = threading.Lock()

def p(number):
    _lock.acquire()
    print(number, end='')
    _lock.release()

# ...

https://docs.python.org/3.8/library/threading.html#threading.Lock

© www.soinside.com 2019 - 2024. All rights reserved.