(一)基础概念线程:是程序执行流的最小单元(线程内部可开线程)、每一个程序都至少有一个线程、线程共享统一进程中的所有资源。
进程:是最小的资源单元(内存资源的分配与调度)线程共享进程中的资源,(每个进程中至少有一个线程(QQ\360))
并发:是指系统具有执行多个任务(动作)的能力并行:是指系统具同一时刻进行多个任务(动作)的能力(是并发子集)
线程与进程关系:一个程序至少有一个进程、每个进程中至少有 一个线程
(1)线程的创建(threading接口)
(1)线程的创建(threading接口)
1.自己创建线程
# sampleOne
import threading
import time
def Hi(name):
print("Hello %s" %name)
time.sleep(3)
if __name__=="__main__":
t1 = threading.Thread(target=Hi,args=("萌萌",))
t1.start()
t2 = threading.Thread(target=Hi, args=("蒙蒙",))
t2.start()
print("end")
2)线程的调用方式
2.创建线程类继承threading.Thread类下的方法
class Mythread(threading.Thread):
def __init__(self, num):
# threading.Thread.__init__(self)
super().__init__()
self.num = num
def run(self):
# music1()
# game1()
print("start num %d" % self.num)
if __name__ == "__main__":
t1 = Mythread(1)
t2 = Mythread(2)
t1.start()
t2.start()
(3)线程阻塞join方法
join:子线程完成之前主线程一直阻塞'''
def music():
print("begin to listen %s" %time.ctime())
time.sleep(3)
print("stop to listen %s" % time.ctime())
def game():
print("begin to game %s" % time.ctime())
time.sleep(5)
print("stop to game %s" % time.ctime())
if __name__ == "__main__":
t1 = threading.Thread(target=music, )
t2 = threading.Thread(target=game, )
t1.start()
t2.start()
# t1.join()
t2.join()
print("over end ")
(4)线程的守护 setDaemon
'''setDaemon:线程守护、子线程跟随主线程一起退'''
def music1():
print("begin to listen %s" %time.ctime())
time.sleep(3)
print("stop to listen %s" % time.ctime())
def game1():
print("begin to game %s" % time.ctime())
time.sleep(5)
print("stop to game %s" % time.ctime())
if __name__ == "__main__":
t1 = threading.Thread(target=music1, )
t2 = threading.Thread(target=game1, )
t2.setDaemon(True)
t1.start()
t2.start()
(5)线程锁与递归锁、结果不是想要的、多个线程操作同一个对象是引发数据安全、只能借助线程锁threading.Lock()
# 开100个线程、每个线程对同一个数递减1
import time
import threading
def sub():
global num
temp = num
time.sleep(0.01)
num = temp-1
if __name__=="__main__":
num=100
for i in range(100):
t = threading.Thread(target=sub)
t.start()
t.join()
'''针对线程安全问题创建线程同步锁'、''输出结果为0、是想要的结果、但有些情况锁也会带来负面的影响
def sub1():
global num
lock.acquire()
temp = num
time.sleep(0.001)
num = temp-1
lock.release()
if __name__ =="__main__":
num=100
lock=threading.Lock()
for i in range(100):
t = threading.Thread(target=sub1)
t.start()
t.join()
print(num)
死锁
classMythread(threading.Thread):'''递归锁 解决死锁'''
defactionA(self):
A.acquire()#count=1
print(self.name, "got A", time.ctime())
B.acquire()#锁中锁 count=2
print(self.name, "got B", time.ctime())
B.release()#count = 1
A.release() #count = 0
defactionB(self):
B.acquire()print(self.name, "got B", time.ctime())
A.acquire()#锁中锁
print(self.name, "got A", time.ctime())
A.release()
B.release()defrun(self):
self.actionA()
self.actionB()if __name__ == "__main__":
L=[]
A=threading.Lock()
B=threading.Lock()for i in range(5):
t=Mythread()
t.start()
L.append(t)for t inL:
t.join()print("ending>>>>>>>>>>")
(5)递归锁RLock()解决死锁问题
创建一把递归锁、替换上面的所有锁 r_lock=threading.RLock()
class Mythread(threading.Thread):
'''递归锁 解决死锁'''
def actionA(self):
r_lock.acquire() # count=1
print(self.name, "got A", time.ctime())
r_lock.acquire() # 锁中锁 count=2
print(self.name, "got B", time.ctime())
r_lock.release() # count = 1
r_lock.release() # count = 0
def actionB(self):
r_lock.acquire()
print(self.name, "got B", time.ctime())
r_lock.acquire()# 锁中锁
print(self.name, "got A", time.ctime())
r_lock.release()
r_lock.release()
def run(self):
self.actionA()
self.actionB()
if __name__ == "__main__":
L = []
r_lock=threading.RLock()
for i in range(5):
t = Mythread()
t.start()
L.append(t)
for t in L:
t.join()
print("ending>>>>>>>>>>")
需求:多个线程删除列表中的最后一个元素并删除
L=[1,3,45,65,76,32,3254]
def pri():
while 1:
a = L[-1]
print(a)
time.sleep(2)
L.remove(a) # 按值来删除
# L.pop(-1) # 按照索引删除
t1=threading.Thread(target=pri,args=())
t1.start()
t2=threading.Thread(target=pri,args=())
t2.start()
看运行结果、
(6)队列queue、是一种数据结构线程使用队列、数据是安全的
import queue
Li=[]
q=queue.Queue() # FIFO
# # q =queue.LifoQueue()# LIFO
# q =queue.PriorityQueue(4) # 优先级s
q.put([4,234])
q.put_nowait([2,"hello"])
q.put([3,{"name","alex"}])
q.put([5,{"gendle":"女"}],)
# q.put(78,block=False) # 队列已满时报错
# q.put_nowait(78) # 队列已满时报错
while 1:
# data=q.get()
data = q.get(block=False)
# data =q.get_nowait() # 为空时报错
print(data)
# print(q.qsize())
# print(q.empty())
# print(q.full())
# print(data[1])
time.sleep(1)
print("----------")
(7)同步对象Event、保证所有的线程中状态完全一致'
import threading
import time
'''同步对象Event 保证所有的线程中状态完全一致'''
class teacher(threading.Thread):
def run(self):
print("teacher: 明天把之前的作业留的作业都完成交上来")
print("状态是否被设定",event.isSet())
event.set()
time.sleep(5)
print("teacher:既然这样那下周一交上来")
event.set()
class student(threading.Thread):
def run(self):
event.wait() # 一旦event.set() 则event.wait()==pass
print("student:啊那么多怎么可能一天完成啊!!!!!")
time.sleep(2)
event.clear()
event.wait()
print("student:ohyear!!")
if __name__ == "__main__":
event = threading.Event()
threads=[]
for i in range(6):
threads.append(student())
threads.append(teacher())
for t in threads:
t.start()
for t in threads:
t.join()
print("所有的都结束了")