线程 1.线程

线程

线程

线程的概念
​	线程是被系统独立调度和分配的基本单位,也是程序执行流的最小单元,可以理解为是程序执行的一条分支
    线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源

主线程
​	当一个程序启动,或有一个进程被操作系统(OS)创建,一个线程也立刻运行。该线程通常叫做程序的主线程,即程序启动就会创建一个主线程
​	主线程的重要性:
​			1.创建子线程
​			2.主线程需要最后完成执行,如执行各种关闭动作

子线程
​	子线程是程序执行的一条分支,子线程启动后会和主线程同时执行

threading模块
    python的threading模块是比较底层的模块,该模块对thread进行了一些包装,使其可以被更加方便的使用

线程
    1.使用多线程并发操作后,花费的时间要短很多
    2.调用 start() 时,才会真正创建线程并开始执行
    3.每个线程都有唯一标识符,来区分线程中的主次关系
    4.主线程:main.Thread.mainfunc或程序主入口,称为主线程,子线程:threading.Thread()创建出来的是子线程
    5.线程数量 = 主线程数 + 子线程数
    6.主线程会等待所有子线程结束后才结束
    7.python会自动为线程指定一个默认的名字
    8.当线程的run()结束时该线程完成
    9.线程的调度是由CPU根据当时的状态自行决定的,所以多个线程的执行是无序、随机的
    10.无法控制线程调度程序,但可以通过其他方式来影响线程的调度方式

线程的参数传递
    子线程的参数在创建线程对象时定义,传递参数有三种方式:
        1.使用tuple传递
        2.使用dict传递
        3.混合使用tuple和dict传递

线程守护
    子线程和主线程的一种约定,当主线程结束时,子线程也结束
    如果没有设置线程守护,即使主程序exit(),子线程也会继续执行,因为主线程默认等待子线程结束才会退出,exit()并没有真正退出

threading
threading.Thread(target=func,[args=()/kwargs={}])
        功能:创建子线程对象
        参数:
            target:子线程执行的函数名
            args=()/kwargs={}:线程的参数列表,args=()为按顺序传递,kwargs={}为按关键字传递

threading.enumerate()
        功能:获取当前所有活跃的线程对象列表
        返回值:以线程对象为元素的list

threading.current_thread()
        功能:获取当前线程对象
        返回值:当前线程对象

obj.start()
        功能:启动子线程

obj.setDaemon(bool)
        功能:开启线程守护,需要在obj.start()前设置
        参数:设置为True时开启线程守护,默认为False,即主线程结束时,子线程依然在执行

obj.join()
        功能:让obj线程优先执行

threading.Lock
        功能:创建互斥锁对象

Lock_obj.acquire()
        功能:激活互斥锁

Lock_obj.release()
        功能:释放互斥锁

import threading
import time

# 使用子线程同时执行多个函数
# 从执行结果可以看出,多线程程序的执行顺序是不确定的
# 执行到sleep()时,线程被阻塞(Blocked),sleep结束后线程进入就绪(Runnable)状态,等待调度,而线程调度将自行选择一个线程执行
def g1(a,b,c):
    print('线程的参数:',a,b,c)
    for i in range(2):
        print('wow',threading.current_thread())
        time.sleep(0.5)

def g2():
    for i in range(2):
        print('dota2',threading.current_thread())
        time.sleep(0.5)

if __name__ == '__main__':
    # 创建线程对象并传递参数
    # t_wow = threading.Thread(target=g1,args=(1,2,3))
    # t_wow = threading.Thread(target=g1,kwargs={'b':2,'c':3,'a':1})
    t_wow = threading.Thread(target=g1,args=(1,),kwargs={'b':2,'c':3})
    t_dota2 = threading.Thread(target=g2)

    # 获取当前活跃的线程列表
    thread_list1 = threading.enumerate()
    print('当前活跃的线程数:',len(thread_list1))
    print('当前活跃的线程:',thread_list1)

    # 启动线程
    t_wow.start()
    t_dota2.start()

    thread_list2 = threading.enumerate()
    print('当前活跃的线程数:',len(thread_list2))
    print('当前活跃的线程:',thread_list2)

    # 定时获取活跃的线程数
    while True:
        thread_num = len(threading.enumerate())
        print('当前活跃的线程数:',thread_num)
        if thread_num <=1:
            break
        time.sleep(0.3)

# 线程守护
def work1():
    for i in range(5):
        print('正在work',i)
        time.sleep(0.5)

if __name__ == '__main__':
    thread_work = threading.Thread(target=work1)
    thread_work.setDaemon(True)
    thread_work.start()

    time.sleep(2)
    print('over')
    exit()
上一篇:threading.local


下一篇:python学习笔记(32)多线程&多进程