简单介绍:线程是程序执行的一个最小单元,当开启多线程时,主线程会创建多个子线程,在python中,默认情况下主线程执行完自己的任务之后就会退出,子线程会继续执行自己的任务,直到自己的任务结束为止。

不设置线程守护(主线程), 默认是不守护主线程的(daemon=False)

import threading
from threading import currentThread

def put_task():
    print(f'{currentThread().name}---->开始输入任务...')
    time.sleep(1)
    print(f'{currentThread().name}---->完成输入任务...')

def get_task():
    print(f'{currentThread().name}---->开始消费任务...')
    time.sleep(1)
    print(f'{currentThread().name}---->完成消费任务...')

upload_thread = threading.Thread(target=put_task,name='子线程1')
upload_thread.start()

download_thread = threading.Thread(target=get_task,name ='子线程2')
download_thread.start()
print('主线程执行到这里了!')

执行输出如下

子线程1---->开始输入任务...
子线程2---->开始消费任务...
主线程执行到这里了!
子线程2---->完成消费任务...
子线程1---->完成输入任务...
  • 在python中,默认情况下(其实就是setDaemon(False)),主线程执行完自己的任务以后,就退出了,此时子线程会继续执行自己的任务,直到自己的任务结束。
  • 由执行输出顺序可知,主线程会先执行,然后子线程1执行遇到阻塞时会切换到子线程2去执行任务,同样当子线程2遇到阻塞时程序也会自动切换到子线程1去执行任务,如此交替直到任务被完成。
  • 主线程会先执行完, 但是并不意味着子线程会跟着主线程结束,主线程执行完以后, 默认等待子线程结束任务。

设置线程守护(daemon=True)

  • 守护线程,是为守护别人而存在,当设置为守护线程后,被守护的主线程不存在后,守护线程也自然不存在
import time
import threading
from threading import currentThread

def put_task():
    print(f'{currentThread().name}---->开始输入任务...')
    time.sleep(1)
    print(f'{currentThread().name}---->完成输入任务...')


def get_task():
    print(f'{currentThread().name}---->开始消费任务...')
    time.sleep(1)
    print(f'{currentThread().name}---->完成消费任务...')


upload_thread = threading.Thread(target=put_task,name='线程1',daemon=True)
upload_thread.start()

download_thread = threading.Thread(target=get_task,name ='线程2')
download_thread.setDaemon(True)
download_thread.start()
print('主线程执行到这里了!')

输出结果

线程1---->开始输入任务...
线程2---->开始消费任务...
主线程执行到这里了!
  • setDaemon(True): 当主线程退出时,后台子线程随机退出。
  • 随着主线程的终止而终止,不管当前主线程下有多少子线程没有执行完毕,都会终止。

join线程同步

  • 在Python多线程编程中,join方法的作用是线程同步
from queue import Queue
import threading
import time

def set_value(queue):
    for num in range(1,5):
        queue.put(num)
        print(f'输入了:{num}')
        time.sleep(1)
    queue.put(True)

def get_value(queue):
    while True:
        value = queue.get()
        if value is True:
            break
        print(f"取出了:{value}")


if __name__ == '__main__':
    queue = Queue(5)

    t1 = threading.Thread(target=set_value, args=(queue, ))
    t2 = threading.Thread(target=get_value, args=(queue, ))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    print('主线程执行到这里了!')

输出结果

输入了:1
取出了:1
输入了:2
取出了:2
输入了:3
取出了:3
输入了:4
取出了:4
主线程执行到这里了!
  • 主线程运行过程中,需要插入一个子线程,且子线程运行结束后,主线程才能继续运行或停止,此时方可用到join()方法
  • join()通俗地说就是是子线程告诉主线程,你要在设置join的位置等我执行完毕你再往下执行。