Python线程,以及多线程带来的数据错乱和死锁的解决方法

摘至本人有道云笔记《Python线程》

1.python多线程的创建

在Python中,同样可以实现多线程,有两个标准模块thread和threading,不过我们主要使用更高级的threading模块

threading模块提供的类:  

   Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。

threading 模块提供的常用方法: 

  threading.currentThread(): 返回当前的线程变量。 

  threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 

  threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

threading 模块提供的常量:

   threading.TIMEOUT_MAX 设置threading全局超时时间

 

Thread类

Thread是线程类,有两种使用方法,直接传入要运行的方法或从Thread继承并覆盖run()

1)将要执行的方法作为参数传给Thread的构造方法

Python线程,以及多线程带来的数据错乱和死锁的解决方法_第1张图片

构造方法: 

Thread(group=None, target=None, name=None, args=(), kwargs={}) 

  group: 线程组,目前还没有实现,库引用中提示必须是None; 

  target: 要执行的方法; 

  name: 线程名; 

  args/kwargs: 要传入方法的参数。

实例方法: 

  isAlive(): 返回线程是否在运行。正在运行指启动后、终止前。 

  get/setName(name): 获取/设置线程名。 

  is/setDaemon(bool): 获取/设置是后台线程(默认前台线程(False))。(在start之前设置)

    如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,主线程和后台线程均停止

         如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止

  start(): 启动线程。 

  join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。

例1:验证了serDeamon(False)(默认)前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,主线程停止。

使用循环创建多线程

Python线程,以及多线程带来的数据错乱和死锁的解决方法_第2张图片

Python线程,以及多线程带来的数据错乱和死锁的解决方法_第3张图片 

例2:继承线程类,子类创建线程

Python线程,以及多线程带来的数据错乱和死锁的解决方法_第4张图片

使用此方法创建线程,注意两点:

1)重写父类的__init__方法,并调用父类的__init__方法

2)实例化子类对象就是创建子线程,使用子线程对象m的start方法启动的是,子类里的run方法(线程要做的事)。

2.线程锁和ThreadLocal

1)线程锁

由于多个线程之间可以共享数据,那随之而来的问题就是:多个线程同时更改一个变量使用一个资源时,就会出现数据错乱死锁等现象。

下面是数据错乱的例子:

理论上如果顺序执行,change方法的每次计算结果都是0。由于两个线程都在同时访问change方法,就会造成数据错乱。

Python线程,以及多线程带来的数据错乱和死锁的解决方法_第5张图片

Python线程,以及多线程带来的数据错乱和死锁的解决方法_第6张图片

 

对于该问题,出现了Lock。 当访问某个资源之前,用Lock.acquire()锁住资源,访问之后,用Lock.release()释放资源。

获得锁的线程用完后一定要释放锁,否则那些苦苦等待锁的线程将永远等待下去,成为死线程。所以用try...finally来确保锁一定会被释放。

Python线程,以及多线程带来的数据错乱和死锁的解决方法_第7张图片

 

多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时,又要小心死锁的发生。

 

你可能感兴趣的:(Python,常用知识点,学习笔记,易出错)