跳转至

多线程


代码1

import threading
import time


def say_something(something):
    for _ in range(3):
        print(something)
        time.sleep(0.5)


def main():
    print(f'开始时间: {time.time()}')
    thread_one = threading.Thread(target=say_something, args=('balabale...',))
    thread_one.start()
    thread_two = threading.Thread(target=say_something, args=('makabaka...',))
    thread_two.start()
    print(f'结束时间: {time.time()}')

if __name__ == '__main__':
    main()

输出:

开始时间: 1659739324.507312
balabale...
makabaka...
结束时间: 1659739324.5080872
balabale...
makabaka...
balabale...
makabaka...

解释:

  • 先执行thread_one后执行thread_two,但balabal和makabaka却是交替输出,证明是多线程
  • 结束时间不是最后输出,是因为主线程代码自上而下执行,thread_one和thread_two则是开启子线程执行
  • 打印结束时间输出后,依旧输出balabal和makabak的原因是,主线程代码执行完毕后在等待子线程代码执行完毕

代码2(线程同步)

import threading
import time


def say_something(something):
    for _ in range(3):
        print(something)
        time.sleep(0.5)


def main():
    print(f'开始时间: {time.time()}')
    thread_one = threading.Thread(target=say_something, args=('balabale...',))
    thread_one.start()
    thread_one.join()
    thread_two = threading.Thread(target=say_something, args=('makabaka...',))
    thread_two.start()
    print(f'结束时间: {time.time()}')

if __name__ == '__main__':
    main()

输出:

开始时间: 1659740206.5571399
balabale...
balabale...
balabale...
makabaka...
结束时间: 1659740208.073323
makabaka...
makabaka...

解释:

对比代码1,thread_one进程执行完毕之后主进程才继续执行,原因是thread_one使用了join方法,即线程同步, 会使主线程进入阻塞状态,直到子线程执行完毕

代码3(守护线程)

import threading
import time


def say_something(something):
    for _ in range(3):
        print(something)
        time.sleep(0.5)


def main():
    print(f'开始时间: {time.time()}')
    thread_one = threading.Thread(target=say_something, args=('balabale...',))
    thread_one.start()
    thread_one.join()
    thread_two = threading.Thread(target=say_something, args=('makabaka...',))
    thread_two.setDaemon(True)
    thread_two.start()
    print(f'结束时间: {time.time()}')

if __name__ == '__main__':
    main()

输出:

开始时间: 1659740624.978488
balabale...
balabale...
balabale...
makabaka...
结束时间: 1659740626.495806

解释:

对比代码2,makaba只输出一次,是因为给thread_two设置守护线程setDaemon(True),即主线执行完毕后立即结束子线程

另外,setDaemon(True)必须在调用stat()之前设置,否则会导致主线程抛出异常,但子线程已经正常运行