python3语法之多线程

1,进程

QQ 要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,内存的对各种资源的管理的集合 就可以成为进程

2,线程

线程是操作系统最小的调度单位,是一串指令的集合

3,进程本身不会执行,他只是一种资源的集合。进程要想操作cpu必须要先创建一个线程。

二:进程与线程的区别

a:线程共享内存空间,进程的内存是独立的

b:同一个进程的线程之间可以直接交流,共享数据,但两个进程想通信,必须通过一个中间代理来实现。

c:创建新线程很简单,创建新进程需要对其父进程进行一次克隆

d:一个线程可以控制和操作同一个进程里的其他线程,但是进程只能父进程操作子进程,子进程之间不能进行操作

三:进程启动速度慢,线程启动速度快。进程和线程不能说谁运行快,因为一个进程里至少包含一个线程,两个是不同的概念。进程与线程比较运行速度,其实是线程与进程里面的线程比较

二:用 threading创建多线程的两种方式(尽量不要用—_thread来创建多线程)

第一种:(基于函数方式创建多线程)

import threading  #导包多线程,threading    创建的是前台线程,当主程序结束后依然会等待前台线程执行结束后整个程序才结束
import time
num1=0
def run(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

class Getthread(threading.Thread):
    def __init__(self,n):
        #super().__init__()
        #super(Getthread,self).__init__()
        threading.Thread.__init__(self) #继承中父类初始化的三种方法
        self.n=n #定义全局变量
    def run(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 小明被糟蹋次数是全局变量,所有线程都能访问到,不加锁的话,多个线程访问同一资源,执行结果会出现错误,


class Getthread(threading.Thread):
    def run(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')

四 5,with mutex 自动上锁和解锁(优化上锁和解锁),相当于上一步中的if mutex.acquire(1) mutex.release()

import threading
import time
小明被蹂躏的次数=0
mutex=threading.Lock()
class Getthread(threading.Thread):
    def run(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解决单个线程反复加锁形成死锁
class  Mythread(threading.Thread):
    def run(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
class Mythreadgetlines(threading.Thread): #创建线程类
    def __init__(self,path):
        super().__init__() #初始化父类
        self.path = path
        self.lines=1
    def run(self): #run函数是thread中自带的函数,不能更改函数名
        reader=csv.reader(open(self.path,"r")) #返回值类似一个存入每行的列表
        lines=0
        for 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=0
for mythread in threadlist: #遍历类对象
    alllines+=mythread.lines  #通过对象来访问属性,获得每个文件的行数
print(alllines)

七:用多线程读取一个文件(将文件均等分割,利用多线程分段处理)

import threading #导入多线程模块
class Getmessage(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

    def run(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() #创建一个锁(对象)
class Getmessage(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
    def run(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)


while True: #死循环,起重复查询的作用
    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()
class Getfile(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

    def run(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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值