线程的第一种写法:
join()加上就变成串行,要等待这个线程完全执行完了,才会起第二个线程
这个程序本身就是一个线程,不是串行是并行,并行的子线程执行与这个程序本身没联系了!!,所以还没等run的子线程全部执行完,就直接执行了后面的代码,默认情况下,主线程不会等子线程执行完毕的,两个根本没关系,这样下面想计算程序运行的时间,要通过一个设置,在主线程里等待子线程的执行结果,
import threading
import time
def run(n):
print("task ",n )
time.sleep(2)
print("task done",n)
start_time = time.time()
t_objs = [] #存线程实例
for i in range(50):
t = threading.Thread(target=run,args=("t-%s" %i ,))
t.start()
t_objs.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里
# for t in t_objs: #循环线程实例列表,等待所有线程执行完毕
# t.join()
print("----------all threads has finished...")
print("cost:",time.time() - start_time)
# run("t1")
# run("t2")
线程的第二种写法:
import threading
import time
class MyThread(threading.Thread):
def __init__(self,n,sleep_time):
super(MyThread,self).__init__()
self.n = n
self.sleep_time = sleep_time
def run(self):
print("runnint task ",self.n )
time.sleep(self.sleep_time)
print("task done,",self.n )
t1 = MyThread("t1",2)
t2 = MyThread("t2",4)
t1.start()
t2.start()
t1.join() #=wait() 等待执行结果
t2.join()
print("main thread....")
----------------------------主线程---------------------
threading.current_thread() 获取主子线程
threading.active_count() 活跃的线程个数51个保持程序本身(主线程)
---守护进程-- 只要主线程执行完毕,不管守护进程有没有执行完毕,等待非守护程序退出程序就立即退出-setDaemon(True)
import threading
import time
def run(n):
print("task ",n )
time.sleep(2)
print("task done",n,threading.current_thread())
start_time = time.time()
t_objs = [] #存线程实例
for i in range(50):
t = threading.Thread(target=run,args=("t-%s" %i ,))
t.setDaemon(True) #把当前线程设置为守护线程
t.start() #一定要在这个之前设置守护线程
t_objs.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里
# for t in t_objs: #循环线程实例列表,等待所有线程执行完毕
# t.join()
time.sleep(2)
print("----------all threads has finished...",threading.current_thread(),threading.active_count())
print("cost:",time.time() - start_time)
# run("t1")
# run("t2")
python的线程调用的是系统的原生线程,python的多线程并发
是个假象,并不是真的痛一时间执行多个线程,而是同一时间只执行一个线程,
因为上下文切换非常快,所以用户感觉起来就是同一时间多并发。
所有对同一变量赋给其他变量时,就要用到线程锁
image.png
image.png
python在解析器上已经加了一把锁GIL,这个GIL只是保证同一时期只有一个线程进入到我的解析器里面
加上锁就相当于变成串行了(但只是在加锁的那变成串行,其它代码执行的逻辑还是多线程),
只要不是对变量进行操作的部分,就放在锁外面就行
---------------线程锁----------
import threading
import time
def run(n):
lock.acquire() #获取一把锁
global num
num +=1
time.sleep(1)
lock.release() #释放锁
lock = threading.Lock() #生成一个锁的实例
num = 0
t_objs = [] #存线程实例
for i in range(50):
t = threading.Thread(target=run,args=("t-%s" %i ,))
t.start()
t_objs.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里
for t in t_objs: #循环线程实例列表,等待所有线程执行完毕
t.join()
print("----------all threads has finished...",threading.current_thread(),threading.active_count())
print("num:",num)
死锁-递归锁:创建多把锁,会发生死锁情况,解决方式,就是用一把锁就行 lock = threading.RLock() --递归锁,可重用
信号量--也是一把锁
import threading, time
def run(n):
semaphore.acquire() #申请一把锁
time.sleep(1)
print("run the thread: %s\n" % n)
semaphore.release()
if __name__ == '__main__':
semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行
for i in range(22):
t = threading.Thread(target=run, args=(i,))
t.start()
while threading.active_count() != 1:
pass # print threading.active_count() #子线程全部执行完
else:
print('----all threads done---')
#print(num)
5个5个执行
EVENT
image.png image.pngimport time
import 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() #变绿灯
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...\033[0m" %name)
light = threading.Thread(target=lighter,)
light.start()
car1 = threading.Thread(target=car,args=("Tesla",))
car1.start()
queue队列
来看看redis:一款内存高速缓存数据库 ok介绍完了
耦合:程序之间的关系 解耦:解除关系
提高效率,不需要干等着,可以去看其他事情
队列可以理解为一个有顺序的容器(数据只有一份,取走了就没了)
q = queue.Queue()创建一个队列 #Queue(maxsize=3)最多放三个
q.put('d1') 往队列里面放数据
q.put('d2')
q.put('d3')
q.qsize() 查看队列里面的数量
q.get() #取最先进入的那个 先入先出,没的选,但去掉没的时候,会卡死 ==》q.get_nowait()可捕捉这个异常,就知道没数据取了
import queue
q = queue.PriorityQueue() #存储数据时可设置优先级队列
q.put((-1,"chenronghua")) #设置优先级
q.put((3,"hanyang"))
q.put((10,"alex"))
q.put((6,"wangsen"))
print(q.get())
print(q.get())
print(q.get())
print(q.get())
# q = queue.LifoQueue()
#
# q.put(1)
# q.put(2)
# q.put(3)
# print(q.get())
# print(q.get())
# print(q.get())
生产者,消费者模型
import threading,time
import queue
q = queue.Queue(maxsize=10)
def Producer(name):
count = 1
while True:
q.put("骨头%s" % count)
print("生产了骨头",count)
count +=1
time.sleep(0.1)
def Consumer(name):
#while q.qsize()>0:
while True:
print("[%s] 取到[%s] 并且吃了它..." %(name, q.get()))
time.sleep(1)
p = threading.Thread(target=Producer,args=("Alex",))
c = threading.Thread(target=Consumer,args=("ChengRonghua",))
c1 = threading.Thread(target=Consumer,args=("王森",))
p.start()
c.start()
c1.start()
网友评论