import threading #导包多线程,threading 创建的是前台线程,当主程序结束后依然会等待前台线程执行结束后整个程序才结束import time
num1=0defrun(num):
time.sleep(2)
global num1 #定义全局变量for i in range(5):
num1+=1
print(num1)
time.sleep(2)
threadinglist=[] #创建多线程列表for i in range(5): #创建5个线程
mythreading=threading.Thread(target=run,args=(i,)) #多线程的书写格式(注意,target对应的是函数名,args对应的是参数,必须是元组的形式,参数可以有任意个)
mythreading.start() #开启多线程
threadinglist.append(mythreading) #添加线程到列表for t in threadinglist:
t.join() #统一阻塞多线程,使其并发执行
print("主线程已结束")
第二种:(基于类创建多线程)
import threading
import win32api
classGetthread(threading.Thread):def__init__(self,n):#super().__init__()#super(Getthread,self).__init__()
threading.Thread.__init__(self) #继承中父类初始化的三种方法
self.n=n #定义全局变量defrun(self):for i in range(self.n)
win32api.MessageBox(0,"内容","标题",i)
threadlist=[]
for i in range(5):
t=Getthread(6) #构造线程类,每循环一次,就创建一个多线程类
t.start() #开启线程# t.join()#如果join放在此处,子线程就不会并发执行,而是以一个一个的执行
threadlist.append(t) #将创建的线程加入线程列表for t in threadlist:
t.join() # 等待五个线程全部创建好之后,再并发执行
print("gameover")
三锁解决线程安全问题
import threading
import time
小明被糟蹋次数=0
mutex=threading.Lock() #创建一个锁(mutex可以当作一个参数传入,也可用global将其定义为类中的全局变量),因为 global 小明被糟蹋次数是全局变量,所有线程都能访问到,不加锁的话,多个线程访问同一资源,执行结果会出现错误,classGetthread(threading.Thread):defrun(self):global mutex # 将mutex设置为全局变量global 小明被糟蹋次数 #将它设为全局变量if mutex.acquire(1): #锁定,1独占,锁不到就一直等待,将共有的资源锁住,让线程一个个的访问for i in range(10000000):
小明被糟蹋次数+=1
mutex.release() #解锁 注意,上锁和解锁位置要对齐
print("小明被糟蹋次数",小明被糟蹋次数)
threadlist=[]
for i in range(5): #依次创建5个线程
t=Getthread() #依次创建5个类线程
t.start() #开启线程
threadlist.append(t) #将创建的线程加入线程列表#注意,上面的循环不会执行,因为下面的join将上面的线程锁住了 for t in threadlist:
t.join() #卡住主线程,等待其他子线程并发执行结束后,再执行主线程
print('gaveover')
import threading
import time
小明被蹂躏的次数=0
mutex=threading.Lock()
classGetthread(threading.Thread):defrun(self):global mutex
global 小明被蹂躏的次数
with mutex: #自动上锁和解锁(优化上锁和解锁),相当于上一步中的if mutex.acquire(1) mutex.release()for i in range(1000000):
小明被蹂躏的次数 +=1
print("小明被蹂躏的次数",小明被蹂躏的次数)
threadlist=[]
for i in range(5):
t=Getthread() #依次创建5个类线程
t.start() #开启线程
threadlist.append(t)
for t in threadlist:
t.join() #卡住主线程,等待其他线程创建好后,并发执行
print("发执行完成")
五: 嵌套锁(加锁不能嵌套,不然会出错,如果非要嵌套锁,创建锁时lock 要改成 Rlock)
import threading
import time
小明在他女神的备胎序列编号=0
mutex=threading.RLock() #Rlock解决单个线程反复加锁形成死锁classMythread(threading.Thread):defrun(self):global mutex
global 小明在他女神的备胎序列编号
if mutex.acquire(1):
小明在他女神的备胎序列编号+=1
print("小明在他女神的备胎序列编号",梁华锋在他女神的备胎序列编号)
if mutex.acquire(1):
小明在他女神的备胎序列编号+=100
print("小明在他女神的备胎序列编号",小明在他女神的备胎序列编号)
mutex.release()
mutex.release()
for i in range(5):
t=Mythread()
t.start()
六:利用多线程读取文件的总行数(多线程分别读取多个文件,每个线程对应一个文件)
import threading #导入前台线程模块import csv #读取csv文件时需要导入的模块,txt文件不需要导入模块import os
classMythreadgetlines(threading.Thread):#创建线程类def__init__(self,path):
super().__init__() #初始化父类
self.path = path
self.lines=1defrun(self):#run函数是thread中自带的函数,不能更改函数名
reader=csv.reader(open(self.path,"r")) #返回值类似一个存入每行的列表
lines=0for item in reader: #类似于将每行从列表中遍历出来(item:行,可随意命名)
lines+=1
self.lines=lines #定义全局变量self.lines,为的是最后外部能访问到每个文件的行数
print(self.lines) #打印每个文件的行数
path1="H:\\学习\\PY教学课程\\第一阶段\\第一阶段项目---尹成\\第36天多线程\\下午\YinchengDay18Down\\csv"#文件夹路径
filenamelist=os.listdir(path1) #将文件夹下的文件名遍历到一个列表储存
threadlist=[] #定义一个多线程列表,用于储存类的多线程对象for filename in filenamelist:
filepath=path1+"\\"+filename
mythread=Mythreadgetlines(filepath) #创建一个类的多线程
mythread.start() #开启多线程
threadlist.append(mythread)
for mythread in threadlist:
mythread.join() #阻塞主线程,当子线程全部结束后,再继续执行下面的主线程
alllines=0for mythread in threadlist: #遍历类对象
alllines+=mythread.lines #通过对象来访问属性,获得每个文件的行数
print(alllines)
七:用多线程读取一个文件(将文件均等分割,利用多线程分段处理)
import threading #导入多线程模块classGetmessage(threading.Thread):def__init__(self,lineslist,istart,iend,findstr):
super().__init__() #父类初始化的三种方法#super(Getmessage,self).__init__()#threading.Thread.__init__(self)
self.lineslist=lineslist
self.istart=istart
self.iend=iend
self.findstr=findstr
defrun(self):#run函数是threading.Thread模块中的函数,会自动调用for i in range(self.istart,self.iend): #通过位置索引来获取行内容
line=self.lineslist[i].decode("gbk",errors="ignore") #解码if line.find(self.findstr)!=-1:
print(line)
path=r"F:\kaifangX.txt"
file=open(path,"rb") #为防止出错,以二进制方式读取
lineslist=file.readlines()
length=len(lineslist) #获取总行数
file.close()
threadlist=[] #创建线程列表
findstr=input("请输入要查询的名字:")
n=10#定义10个线程for i in range(n-1): # 先提取前九个线程
mythread=Getmessage(lineslist,i*(length//(n-1)),(i+1)*(length//(n-1)),findstr) #创建类线程对象,将文件均等分割,将分割后的索引传入
mythread.start() #开启线程
threadlist.append(mythread) #将线程装入列表
mythread=Getmessage(lineslist,length//(n-1)*(n-1),length,findstr) #创建最后一个线程
mythread.start()
threadlist.append(mythread)
for mythread in threadlist: #卡住主线程,等待所有线程结束,再继续执行主线程
mythread.join()
print("查找结束")
七:用多线程读取一个文件,然后在分类写入另一个文件(将文件均等分割,利用多线程分段处理后再写入)
import threading
mutex = threading.Lock() #创建一个锁(对象)classGetmessage(threading.Thread):def__init__(self,lineslist,istart,iend,findstr,savefile):
super().__init__() # 父类初始化的三种方式#super(Getmessage,self).__init__()#threading.Thread.__init__(self)
self.lineslist=lineslist
self.istart=istart
self.iend=iend
self.findstr=findstr
self.savefile=savefile
defrun(self):
list1=[]
for i in range(self.istart,self.iend): #遍历索引列表(要理解索引对字符串,元组,列表的重要性)
line=self.lineslist[i].decode("gbk","ignore") #通过索引取出每行内容if line.find(self.findstr)!=-1:
list1.append(line)
print(self.getName(),line) #self.getName()是threading里的内置函数,得到线程名字with mutex: #锁定下面的循环,for line in list1:
self.savefile.write(line)
whileTrue: #死循环,起重复查询的作用
findstr=input("请输入要查询的内容:")
path=r"H:\kaifangX.txt"
file=open(path,"rb")
lineslist=file.readlines()
length=len(lineslist) #计算文件长度
file.close() #别忘记关闭文件
savepath="C:\\Users\\Administrator\\Desktop\\1"+"\\"+findstr+".txt"#定义保存文件的名字,当文件名存在时,会覆盖,不存在时,则会自动创建
savefile=open(savepath,"w")
n=10#定义10个线程
threadlist=[]
for i in range(n-1): #遍历线程,注意文件的均等分割
mythread=Getmessage(lineslist,i*(length//(n-1)),(i+1)*(length//(n-1)),findstr,savefile) #创建线程
mythread.start() #开启线程
threadlist.append(mythread)
mythread=Getmessage(lineslist,(n-1)*(length//(n-1)),length,findstr,savefile)
mythread.start()
threadlist.append(mythread)
for mythread in threadlist: # 阻塞主线程,当子线程全部结束时,才继续执行剩下的主线程
mythread.join()
savefile.close() #关闭写入的文件
八:接着上面的七,将文件多线程读取并写入。
import threading
mutex=threading.Lock()
classGetfile(threading.Thread):def__init__(self,readrootpath,lineslist,istart,iend,writefile):
super().__init__()
self.readrootpath=readrootpath
self.lineslist=lineslist
self.istart=istart
self.iend=iend
self.writefile=writefile
defrun(self):with mutex:
for i in range(self.istart,self.iend):
line=self.lineslist[i]
self.writefile.write(line)
readrootpath=r"C:\Users\Administrator\Desktop\2\11.txt"
lineslist=open(readrootpath,"r",errors="ignore").readlines()
length=len(lineslist)
n=10
threadlist=[]
for i in range(n-1):
writerootpath="C:\\Users\\Administrator\\Desktop\\2"+"\\"+str(i*(length//(n-1)))+"--"+str((i+1)*(length//(n-1)))+".txt"
writefile=open(writerootpath,"w")
mythread=Getfile(readrootpath,lineslist,i*(length//(n-1)),(i+1)*(length//(n-1)),writefile)
mythread.start()
threadlist.append(mythread)
writerootpath = "C:\\Users\\Administrator\\Desktop\\2"+ "\\" + str((n - 1) * (length // (n - 1))) + "--" + str(length) + ".txt"
writefile = open(writerootpath, "w")
mythread=Getfile(readrootpath,lineslist,(n-1)*(length//(n-1)),length,writefile)
mythread.start()
threadlist.append(mythread)
for mythread in threadlist:
mythread.join()
writefile.close()