学习视频地址:https://www.bilibili.com/video/av16944429?from=search&seid=1740585247496824985
莫凡36分钟
#import threading
#import time
# def thread_job():
# # print("this is an added thread,number is %s"%threading.current_thread())
# print("T1 start!\n")
# for i in range(10):
# time.sleep(0.1)
# print("T1 finish\n")
#
# def T2_job():
# print("T2 start\n")
# print("T2 finish\n")
# def main():
# #添加线程
# # addded_thread = threading.Thread(target = thread_job()) #新建线程并给工作
# # addded_thread.start()
# # print(threading.active_count())
# # print(threading.enumerate())
# # print(threading.current_thread())
# #join功能
# added_thread = threading.Thread(target = thread_job,name = 'T1')
# thread2 = threading.Thread(target = T2_job,name = 'T2')
# added_thread.start()
# thread2.start()
# #thread2.join() #作用是必须要等added_thread结束后才会执行后面,插队顺序执行
# print("all done\n")
#queue功能
# from queue import Queue
# def job(L,q):
# for i in range(len(L)):
# L[i] = L[i]**2
# q.put(L)
# def multithreading():
# q = Queue()
# threads = []
# data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]
# for i in range(4):
# t = threading.Thread(target=job,args=(data[i],q))
# t.start()
# threads.append(t)
# for thread in threads: #把每个线程附加到主线程,并行执行
# thread.join()
# results = []
# for _ in range(4):
# results.append(q.get())
# print(results)
# if __name__ == '__main__':
# multithreading()
#第二个线程要用到第一个线程的处理结果,所以第一个线程加锁
import threading
import time
def job1():
global A
lock.acquire()
for i in range(10):
A += 1
time.sleep(1)
print('job1',A)
lock.release()
def job2():
global A
lock.acquire()
for i in range(10):
A += 10
time.sleep(1)
print('job2',A)
lock.release()
if __name__ == '__main__':
lock = threading.Lock()
A = 0
t1 = threading.Thread(target=job1)
t2 = threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
视频:https://www.bilibili.com/video/av62631195/?p=534
多线程主要解决并发问题,主线程(一定保证活着),次线程。主线程死了,子线程也不会输出
骚扰局域网https://www.bilibili.com/video/av62631195/?p=537。。。多线程解决轰炸问题
线程冲突:
join()主线程等待子线程执行完毕,解决线程冲突的一种办法,不需要阻塞主线程
集合list,每创建一个线程对象,append加入线程集合。在一个for循环,每个线程join一下
基于类解决线程冲突,mutex = threading.Lock()创建锁
run里面if mutex.acquire(1) 锁住成功继续干活,没有锁住一直等待。1代表独占。。。结束后mutex.release()
死锁:boymutex = threading.Lock() girlnumtex = threading.Lock()
一个线程不能对一个资源反复加锁,Rlock避免这种情况发生 mutex = threading.RLock()
import threading
import time
boymutex = threading.Lock()
girlmutex = threading.Lock()
#死锁!!!
class boyThread(threading.Thread):
def run(self):
if boymutex.acquire(1):
print(self.name+'boy is sorry up')
time.sleep(3)
if girlmutex.acquire(1):
print("boy is sorry down")
girlmutex.release()
boymutex.release()
class girlThread(threading.Thread):
def run(self):
if girlmutex.acquire(1):
print(self.name+"girl is sorry up")
time.sleep(3)
girlmutex.release()
if(boymutex.acquire(1)):
print("girl is sorry down")
boymutex.release()
#girlmutex.release() #如果女的先道歉
boy = boyThread()
boy.start()
girl = girlThread()
girl.start()
创建线程的三种方式:构造函数创建(不考虑冲突和通信),通过函数创建(不考虑冲突和通信),通过类继承创建
信号量限制线程的数量
import threading
import time
#sem = threading.Semaphore(2) #限制线程的最大数量为2
bar = threading.Barrier(2) #必须凑一对才能一起执行
#为了合理利用资源,10000,必须N=10才能执行 ,凑够10个才执行
def gothread():
# with sem: #锁定数量
for i in range(10):
print(threading.current_thread().name,i)
time.sleep(1)
print("")
for i in range(5):
threading.Thread(target=gothread).start()
信号事件:
import time
import threading
def goevent():
e = threading.Event() #事件
def go():
e.wait()#等待
e.clear()#清理
print("go")
threading.Thread(target=go).start() #开启一个线程
return e
t = goevent()
time.sleep(5)
t.set() #激发事件
lock解决线程同步,event解决线程通信,condition解决线程通信与事件
线程通信:
线程同步和线程通信差别:
线程通信原理:
condition原理:
import time
import threading
def go1():
with cond:
for i in range(1,10,2):
time.sleep(1)
print(threading.current_thread().name,i)
cond.notify()
cond.wait()
def go2():
with cond:
for i in range(0,10,2):
time.sleep(1)
print(threading.current_thread().name,i)
cond.wait()
cond.notify()
cond = threading.Condition()
threading.Thread(target=go2).start()
threading.Thread(target=go1).start()
生产者消费者:
import threading
import queue
import time
import random
#生产者
class creatorThread(threading.Thread):
def __init__(self,index,myqueue):
threading.Thread.__init__(self)
self.index=index
self.myqueue=myqueue
def run(self):
while True:
time.sleep(3) #3s生产一个
num = random.randint(1,1000000)#随机数
self.myqueue.put("input生产者"+str(self.index)+"天上的星星"+str(num))
print("input生产者"+str(self.index)+"天上的星星"+str(num))
self.myqueue.task_done() #完成任务
#消费者
class buyerThread(threading.Thread):
def __init__(self,index,myqueue):
threading.Thread.__init__(self)
self.index=index
self.myqueue=myqueue
def run(self):
while True:
time.sleep(1)
item=self.myqueue.get()
if item is None:
break
print("客户",self.index,"买到物品",item)
self.myqueue.task_done() #完成任务
myqueue = queue.Queue(10) #0代表无线,10最大容量
for i in range(3):
creatorThread(i,myqueue).start() #生产者
for i in range(8):
buyerThread(i,myqueue).start() #消费者
线程池:前提是假定线程池中的每个线程没有冲突
import time
import threadpool #库不成熟
def show(str):
print("hello ",str)
time.sleep(2)
namelist = ["高清化","heehehehh","sssss"]
start_time = time.time()
pool = threadpool.ThreadPool(10)#最大容量10个
requests = threadpool.makeRequests(show,namelist) #设置参数,函数,参数列表
for req in requests: #遍历每个请求,并开始执行
pool.pushRequest(req) #压入线程池并开始执行
end_time = time.time()
print(end_time-start_time)