1 threading_lesson
import time
import threading
def music(stype,name):
print("%s 开始听%s音乐"%(name,stype),time.ctime())
time.sleep(3)
print("%s 结束听%s音乐" % (name, stype), time.ctime())
def code(stype,name):
print("%s 开始敲%s代码"%(name,stype),time.ctime())
time.sleep(5)
print("%s 结束敲%s代码" % (name, stype), time.ctime())
if __name__ == "__main__":
t1=threading.Thread(target=music,args=("rock","alex"))
"""固定格式,target=函数名,args=元组形式的函数实参,实例化一个子线程对象
"""
t1.start()
t2 = threading.Thread(target=code, args=("rock", "alex"))
t2.start()
t1.join()
t2.join()
print("ending.....",time.ctime())
2 lesson2-setDaemen
import time
import threading
def music(stype,name):
print("%s 开始听%s音乐"%(name,stype),time.ctime())
time.sleep(3)
print("%s 结束听%s音乐" % (name, stype), time.ctime())
def code(stype,name):
print("%s 开始敲%s代码"%(name,stype),time.ctime())
time.sleep(5)
print("%s 结束敲%s代码" % (name, stype), time.ctime())
if __name__ == "__main__":
t1=threading.Thread(target=music,args=("rock","alex"))
t1.setDaemon(True)
"""要在调用start()之前声明,在其他线程执行结束时,无论自己是否执行完毕,立即停止执行
和t1.join()效果相反。注意后面的参数Ture
"""
t1.start()
t2 = threading.Thread(target=code, args=("rock", "alex"))
t2.setDaemon(True)
print("ending.....",time.ctime())
3 线程的继承实例化
import time
import threading
class MyThread(threading.Thread):
def __init__(self,num):
super().__init__()
self.num=num
def run(self) -> None:
print(self.num)
time.sleep(8)
print("ok")
if __name__ =="__main__":
t1=MyThread(1)
t1.setDaemon(True)
t1.start()
print("ending....")
4 线程安全问题
"""由于GIL存在而引发的一个问题,首先同一时刻只能有一个线程被cpu执行。在一个进程中可能有多个
线程,共用进程的内存,它们在需要被cpu执行的过程中是竞争关系,又由于用多道技术进行时间轮循实现并发效果
就可能出现线程安全问题
有IO阻塞就立即切换(比如sleep),没有的话就是计算密集型
"""
"""解决方法:在适当地方加互斥锁
"""
import time
import threading
lock=threading.Lock()
num=100
def mul():
global num
lock.acquire()
temp=num
time.sleep(0.000001)
temp-=1
num=temp
lock.release()
l=[]
for i in range(100):
t=threading.Thread(target=mul)
t.start()
l.append(t)
for k in l:
k.join()
print(num)
5死锁和递归锁
"""前面讲到的线程安全问题可以通过加同步锁的方式来解决
这种锁的实例化方法是lock=threading.Lock(),这种锁只能同时被一个线程使用,并且只能使用一次
如果两个线程都有一把锁,又彼此要对方的锁,则会出现死锁
这个时候要使用递归锁 r_lock=threading.Rlock()
它的内部有一个指针计数器,无线程使用时为0,有线程使用一次为1,这时别的线程不能使用
绑定线程再使用一次,计数器则为2.。。。施放一次计数器减一,为0时回归初始化状态
"""
6同步对象event
"""Event内部包含了一个标志位,初始的时候为false。
可以使用使用set()来将其设置为true;
或者使用clear()将其从新设置为false;
可以使用is_set()来检查标志位的状态;
另一个最重要的函数就是wait(timeout=None),用来阻塞当前线程,
直到event的内部标志位被设置为true或者timeout超时。如果内部标志位为true则wait()函数理解返回。
import threading
event=threading.Event() #创建同步对象
"""
import threading
import time
class MyThread(threading.Thread):
def __init__(self, signal):
threading.Thread.__init__(self)
self.singal = signal
def run(self):
print ("I am %s,I will sleep ..."%self.name)
self.singal.wait()
print ("I am %s, I awake..." %self.name)
if __name__ == "__main__":
singal = threading.Event()
for t in range(0, 3):
thread = MyThread(singal)
thread.start()
print ("main thread sleep 3 seconds... ")
time.sleep(3)
singal.set()
7信号量Semaphore
"""也是一种锁(第三把),锁同时能有几个线程进入cpu,默认为1
"""
import threading
import time
class Mythread(threading.Thread):
def __init__(self,num):
threading.Thread.__init__(self)
self.num=num
def run(self):
semaphore.acquire()
print(self.name,self.num)
time.sleep(2)
semaphore.release()
semaphore=threading.Semaphore(5)
l=[]
if __name__=="__main__":
for i in range(100):
t=Mythread(i+1)
l.append(t)
for i in l:
i.start()
8多线程队列
'''
eg:多线程拿出列表(也可以是其他,只是存储数据的一种结构)的最后一个值可能会报错
'''
"""两个线程都拿到了列表最后一个5,第一个线程删除之后,第二个线程删除时报错
这种也是一个线程安全问题,主要只有列表这种数据结构引起的
这里到引入多线程队列解决问题
"""
import queue
q=queue.Queue(5)
"""#创建一个队列对象,参数5表示这个队列最多能放5个元素,
这种形式下创建的是FIFI(先进先出)类型的队列
还有LIFO(后进先出)q=queue.LifoQueue() 用法相同
还有自定义优先级q=queue.PriorityQueue() 单独有实例
"""
q.put(3,block=True)
q.put("alex")
q.put([1,2,5,3])
q.put({"a":222})
q.put((2,31,4))
while True:
date=q.get(block=True)
print(date)
9生产者消费者模型
import time
import threading
import queue
q=queue.Queue(10)
def produce_baozi(name):
for i in range(1,13):
time.sleep(1)
print("%s的第%s个包子做好了" % (name,i))
q.put(i)
q.task_done()
def consume_baozi(name):
for i in range(1, 5):
q.join()
date=q.get()
time.sleep(1)
print("%s吃了第%s个包子"%(name,date))
p1=threading.Thread(target=produce_baozi,args=("p1",))
c2=threading.Thread(target=consume_baozi,args=("c2",))
c3=threading.Thread(target=consume_baozi,args=("c3",))
c1=threading.Thread(target=consume_baozi,args=("c1",))
c1.start()
c2.start()
c3.start()
p1.start()
c1.join()
c2.join()
c3.join()
p1.join()
print("end...")