#线程锁 又叫 互斥锁(Mutex)
import threading,time
def run(n):
lock.acquire() #申请锁
global num
num+=1
time.sleep(1)
lock.release() #释放锁
lock = threading.Lock() #生成实例
num = 0
t_obj = [] #存放线程实例
for i in range(1000):
t = threading.Thread(target=run,args=("t-%s"%i,))
t.start()
t_obj.append(t)
#为了不阻塞后面线程的启动,不在这里join(),先放到列表里
for r in t_obj: #遍历线程实例列表,等待所有线程执行完毕
t.join() #join()的作用是为了防止子线程没结束主线程就先结束
# 表明主线程会等待子线程执行完毕再结束。
print("finished..",threading.current_thread(),threading.active_count())
print("num:",num)
#ubuntu python2.6 可以看到num小于1000,原因如下
#python2.6每100条指令换一次gil锁,换线程执行
#thread线程执行,100条指令到了还没执行完,释放锁,不执行了,换thread2线程执行
#thread2申请锁,假设thread2执行完了,赋值count=1并释放锁
#这时thread1又可以(再次)执行了,申请gil锁,重复之前第一次执行的所有过程
#执行完count++,count=1,因为线程1执行了一半,记住了上下文放在寄存器里
#再次执行的时候从寄存器里拿数据,运算完还是1,把线程2的给覆盖了,结果还是1
每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。
# Python在同一时刻只允许一个线程修改数据,线程锁,解决上面问题
# 加了锁程序就变串行了,所以使用时数据量不要特别大,获取锁立刻释放
守护线程
import threading,time
def run(n):
print("task",n)
time.sleep(2)
print("done")
start_time= time.time()
for i in range(50):
t = threading.Thread(target=run,args=("t-%s"%i,))
t.setDaemon(True) #把当前线程设置为守护线程,主线程结束整个程序结束
#socket一个连接启动一个线程,设置为守护线程,当socketserver停掉整个
#程序结束,不用等线程结束
t.start()
#查看主线程和当前线程数
print("finished..",threading.current_thread(),threading.active_count())
print("cost:",time.time()-start_time)
简单线程
普通方法
import threading,time
def run(n):
print("task",n)
time.sleep(2)
t1=threading.Thread(target=run,args=("t1",)) t2=threading.Thread(target=run,args=("t2",))
t1.start()
t2.start()
类方法
class MyThread(threading.Thread):
def __init__(self,n):
super(MyThread,self).__init__()
self.n=n
def run(self): #必须是run
print("running task",self.n)
t1=MyThread("t1")
t2=MyThread("t2")
t1.start()
t2.start()
线程间通信,使用event
# 通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子,
# 即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯#
# 停,绿灯行的规则。
# event.setO
# event.clear()
# If the flag is set,the wait method doesn't do anything.
# 标志位设定了,代表绿灯,直接通行
# If the flag is cleared,wait will block until it becomes set again.
# 标志位被清空,代表红灯,wait等待变绿灯
# Any number of threads may wait for the same event.
import time,threading
event=threading.Event()
def lighter():
count = 0
event.set() #先设置绿灯
while True:
if count >5 and count <10: #改成红灯
event.clear() #把标志位清了
print("\033[41;1mred light is on...\033[0m")
elif count>10:
event.set() #变绿灯
print("\033[42;1mgreen light is on...\033[0m")
count=0
else:
print("\033[42;1mgreen light is on...\033[0m")
time.sleep(1)
count+=1
def car(name):
while True:
if event.is_set(): #代表绿灯
print("[%s] running..."%name)
time.sleep(1)
else:
print("[%s] sees red light,waiting..." % name)
event.wait()
print("\033[34;1m[%s] green light is on, start going..." % name)
light=threading.Thread(target=lighter,)
light.start()
car1 = threading.Thread(target=car,args=("tesila",))
car1.start()
线程间通信,使用event
# 通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子,
# 即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯#
# 停,绿灯行的规则。
# event.setO
# event.clear()
# If the flag is set,the wait method doesn't do anything.
# 标志位设定了,代表绿灯,直接通行
# If the flag is cleared,wait will block until it becomes set again.
# 标志位被清空,代表红灯,wait等待变绿灯
# Any number of threads may wait for the same event.
import time,threading
event=threading.Event()
def lighter():
count = 0
event.set() #先设置绿灯
while True:
if count >5 and count <10: #改成红灯
event.clear() #把标志位清了
print("\033[41;1mred light is on...\033[0m")
elif count>10:
event.set() #变绿灯
print("\033[42;1mgreen light is on...\033[0m")
count=0
else:
print("\033[42;1mgreen light is on...\033[0m")
time.sleep(1)
count+=1
def car(name):
while True:
if event.is_set(): #代表绿灯
print("[%s] running..."%name)
time.sleep(1)
else:
print("[%s] sees red light,waiting..." % name)
event.wait()
print("\033[34;1m[%s] green light is on, start going..." % name)
light=threading.Thread(target=lighter,)
light.start()
car1 = threading.Thread(target=car,args=("tesila",))
car1.start()