1.多线程的使用

(1)把一个函数按子线程的方式执行

from threading import Thread

t = Thread(target=func, args=(x,))  # 创建线程   target=函数名   args=函数的参数(放入的是实参)

t.setDaemon(True)  # 主线程守护   只要主线程的任务执行完 程序就结束

# 查看当前任务是由哪个线程执行的
threading.current_thread()
# 查看运行的程序有的运行的线程列表
threading.enumerate()
# 查看运行的程序有多少个线程在运行
len(threading.enumerate())
threading.active_count()
t.join()   # 线程同步(一个线程执行任务完成 下个线程再执行任务)

t.start()   # 启动线程执行任务

(2)自定义线程类

class MyThread(threading.Thread):

    def __init__(self, name):
        # 如果自定义线程中重写init方法 子类需要调用父类同名方法
        super(MyThread, self).__init__()
        # 属性
        self.name = name

    def work1(self):

        print(threading.current_thread())
        print(self.name, "工作1")

    def work2(self):
        print(threading.current_thread())
        print(self.name, "工作2")

    # 如果自定义线程 使用线程执行多任务
    # 必须实现一个方法名叫做run的方法
    def run(self):
        print(threading.current_thread())
        self.work1()
        self.work2()

if __name__ == '__main__':
    # 创建一个子线程 (自定义线程类)
    my_thread = MyThread("自定义线程")
    # 启动线程
    my_thread.start()

2.多线程共享全局变量问题

  • 在一个进程内的所有线程共享全局变量,很方便在多个线程间共享数据
  • 线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)
  • 如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确

3.互斥锁

threading模块中定义了Lock类,可以方便的处理锁定:

# 创建锁
mutex = threading.Lock()

# 锁定
mutex.acquire()

# 释放
mutex.release()

注意:

  • 如果这个锁之前是没有上锁的,那么acquire不会堵塞
  • 如果在调用acquire对这个锁上锁之前 它已经被 其他线程上了锁,那么此时acquire会堵塞,直到这个锁被解锁为止

锁的好处:

  • 确保了某段关键代码只能由一个线程从头到尾完整地执行

锁的坏处:

  • 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了
  • 由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁