Python3的threading 学习笔记
作者:罗寅兵日期:2012-11-14
一、一、线程基础
线程基础1、线程状态
2、线程互斥锁同步控制
多个线程需要修改同一共享数据时,需要进行同步控制,引入了锁的概念。锁定池锁定
a 、同一时间可能有多个线程在锁定池中,它们处于同步阻塞状态竞争锁定;
b 、同一时间只能有一个线程获得锁定处于运行状态。
3、条件变量(线程通信)
有的线程需要预备条件才能干活。
锁定池
锁定等待池锁定池锁定
等待池二、二、threading threading threading:线程创建、启动、睡眠、退出
:线程创建、启动、睡眠、退出1、方法一:将要执行的函数作为参数传递给threading.Thread()
以上例子创建了5个线程去执行func 函数。获得的结果可能是5000,但也有时候会出现错误,解决方法请继续阅读下文。
要点:
a.threading.Thread(target=func,args=(10,)):func 为函数名,args 为函数参数(必须以元组的形式传递);
c.函数运行结束,线程也就结束;
d.tim
e.sleep():线程进入睡眠,处于IO 阻塞状态。
1、方法二:继承threading.Thread()threading.Thread()类,并重写类,并重写run()run()【推荐使用】
【推荐使用】#!/usr/bin/env python3
#-*-coding:utf-8-*-
import threading,time
def func(n):
global count
time.sleep(0.1)
for i in range(n):
count +=1
if __name__==’__main__’:
count =0
threads =[]
for i in range(5):
threads.append(threading.Thread(target=func,args=(1000,)))
for t in threads:
t.start()
time.sleep(5)print(‘count:’,count)
#!/usr/bin/env python3
#-*-coding:utf-8-*-
import threading,time
class myThread(threading.Thread):
def __init__(self,n):
threading.Thread.__init__(self)
def run(self):
global count
for i in Thread_n):
count +=1
if __name__==’__main__’:
count =0
threads =[]
for i in range(5):
threads.append(myThread(1000))
for t in threads:
t.start()
time.sleep(5)
print(‘count:’,count)
要点:
a.threading.Thread.__init__(self):回调父类方法。如果你重写了__init__()方法,这一步是必须的,否则出错。三、三、threading threading threading:线程同步锁互斥控制
:线程同步锁互斥控制因为线程是乱序执行的,在某种情况下上面的两个例子,输出的结果可能不是预期的值。
我将第2例的线程类修改下,让问题更加突出,然后你每次运行的时候再把线程数也修改下,并计算出预期结果和运行结果对比。一定要多试几次哦。
是不是输出的结果和预期结果不一致啊,呵呵!因为多个线程都在同时操作同一个共享资源,所以造成资源破坏。不过我们可以通过同步锁来解决这种问题:
要点:
a.
lock =threading.Lock():创建锁;b.lock.acquire([timeount]):请求锁定,如果设定了timeout ,则在超时后通过返回值可以判断是否得到了锁,
class myThread(threading.Thread):
def __init__(self,n):
threading.Thread.__init__(self)
def run(self):
global count
for i in Thread_n):
__Temp =count
time.sleep(0.0001)
count =__Temp +1
#!/usr/bin/env python3
#-*-coding:utf-8-*-
import threading,time
class myThread(threading.Thread):
def __init__(self,n):
threading.Thread.__init__(self)
def run(self):
global count
for i in Thread_n):
if lock.acquire():
__Temp =count
time.sleep(0.0001)
count =__Temp +1
if __name__==’__main__’:
count =0
lock =threading.Lock()#同步锁,也称互斥量
threads =[]
for i in range(5):
threads.append(myThread(1000))
for t in threads:
t.start()
time.sleep(5)
print(‘count:’,count)
从而可以进行一些其他的处理;lease():释放锁定。
四、四、threading threading threading:线程死锁和递归锁
:线程死锁和递归锁1、死锁
a.在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁,
因为系统判断这部分资源都正在使用,所有这两个线程在无外力作用下将一直等待下去。下面是一个死锁的例子:
b.当一个线程已经获得了锁,再此请求锁也会出现死锁,请看下面的例子:
#!/usr/bin/env python3
#-*-coding:utf-8-*-
import threading,time
class myThread(threading.Thread):
def doA(self):
if lockA.acquire():
print(self.name,”got lockA.”)
time.sleep(0.0001)
if lockB.acquire():
print(self.name,”got lockB”)
def doB(self):
if lockB.acquire():
print(self.name,”got lockB.”)
time.sleep(0.0001)
if lockA.acquire():lady.gaga
print(self.name,”got lockA”)
def run(self):
self.doA()
self.doB()
if __name__==’__main__’:
lockA =threading.Lock()
lockB =threading.Lock()
threads =[]
for i in range(5):
threads.append(myThread())
for t in threads:
t.start()
for t in threads:
t.join()#等待线程结束,后面再讲。
2、递归锁(也称可重入锁)
上一例子的死锁,我们可以用递归锁解决:
为了支持在同一线程中多次请求同一资源,python 提供了“可重入锁”:threading.RLock 。RLock 内部维护着一个Lock 和一个counter 变量,counter 记录了acquire 的次数,从而使得资源可以被多次require 。直到一个线程所有的acquire 都被release ,其他的线程才能获得资源。
递归锁一般应用于复杂的逻辑。
五、五、threading threading threading:条件变量同步
:条件变量同步有一类线程需要满足条件之后才能够继续执行,Python 提供了threading.Condition 对象用于条件变量线程的支持,它除了能提供RLock()或Lock()的方法外,还提供了wait()、notify()、notifyAll()方法。
lock_con =threading.Condition([Lock/Rlock]):锁是可选选项,不传人锁,对象自动创建一个RLock()。
wait():条件不满足时调用,线程会释放锁并进入等待阻塞;
notify():条件创造后调用,通知等待池激活一个线程;#!/usr/bin/env python3
#-*-coding:utf-8-*-
import threading,time
import random
class myThread(threading.Thread):
def toHex(self):
global L
if lock.acquire(1):
for i in range(len(L)):
if type(L[i])is int:L[i]=”{:X}”.format(L[i])
else:
print(self.name,“错误,系统忙”)
def run(self):
global L
if lock.acquire(1):
L.append(random.randint(0,15))
else:
print(self.name,“错误,系统忙”)
if __name__==’__main__’:
L =[]
lock =threading.Lock()
threads =[]
for i in range(5):
threads.append(myThread())
for t in threads:
t.start()
for t in threads:
t.join()#等待线程结束,后面再讲。
#lock =threading.Lock()注释掉此行,并加入下行。
lock =threading.RLock()
发布评论