• Python之多进程多线程


    进程是多个资源的集合

    线程就是进程里面具体干活的

    线程和线程之间是相互独立的

    多线程:适用于IO密集型任务

    多进程:适用于CPU密集型任务

    一、多线程

    线程需要使用threading模块

    启动线程的方法:

    threading.Thread(target=XXX,args=('xxx','xxx')) #target接的是函数名,args接的是传递的参数,如果只有一个参数要这么写args=('xxx',)

    通过threading.Thread实例出来的线程都是子线程,只有最先开始的一个线程是主线程

    写一个简单的多线程

    import threading
    
    def down_load():
        time.sleep(1)
        print('运行完了')
    
    for i in range(5): #循环5次,即启动5个线程
        t=threading.Thread(target=down_load) #实例化一个线程
        t.start() #启动线程
    
    print(threading.active_count()) #查看当前线个程数
    print(threading.current_thread())#查看当前线程

    如果说我现在想看一下启动的线程全部执行完要多久,这就涉及到线程等待,线程等待是用join,使用jion会比较麻烦,可以用一个while循环的方式来处理。

    import threading
    import time
    
    def down_load():
        time.sleep(1)
        print('运行完了')
    
    start_time=time.time()
    for i in range(5): #循环5次,即启动5个线程
        t=threading.Thread(target=down_load) #实例化一个线程
        t.start() #启动线程
    while threading.active_count()!=1: #判断线程个数不等于1就一直循环,直到等于1,结束循环
        pass
    print(threading.active_count()) #查看当前线程个数
    print(threading.current_thread())#查看当前线程
    
    end_time=time.time()
    print('时间:',end_time-start_time)

    例子:

    分别用单线程和多线程两种方式来看一下下载图片的执行时间:

    mport requests,time,threading
    from hashlib import md5
    def down_load_pic(url):
        req = requests.get(url)
        m = md5(url.encode())
        with open( m.hexdigest()+'.png','wb') as fw:
            fw.write(req.content)
    
    url_list = ['http://www.nnzhp.cn/wp-content/uploads/2019/10/f410afea8b23fa401505a1449a41a133.png',
                'http://www.nnzhp.cn/wp-content/uploads/2019/11/481b5135e75c764b32b224c5650a8df5.png',
                'http://www.nnzhp.cn/wp-content/uploads/2019/11/b23755cdea210cfec903333c5cce6895.png',
                'http://www.nnzhp.cn/wp-content/uploads/2019/11/542824dde1dbd29ec61ad5ea867ef245.png']
    
    # 串行运行方式下载(单线程)
    # start_time=time.time()
    # for url in url_list:
    #     down_load_pic(url)
    # end_time=time.time()
    #
    # print(end_time-start_time)
    
    
    #并行的方式(多线程)
    start_time=time.time()
    for url in url_list:
        t=threading.Thread(target=down_load_pic,args=(url,))  #只有一个参数要这么写(url,)
        t.start()
        
    while threading.activeCount()!=1:
        pass
    
    end_time=time.time()
    print(end_time-start_time)
    • 线程池

    线程池需要使用threadpool模块,需手动安装一下:pip install threadpool

    线程池可以自动计算分配数据,不需要我们手动start,还是以下载图片为例:

    import threadpool
    import requests,time,threading
    from hashlib import md5
    def down_load_pic(url):
        req = requests.get(url)
        m = md5(url.encode())
        with open( m.hexdigest()+'.png','wb') as fw:
            fw.write(req.content)
    
    url_list = ['http://www.nnzhp.cn/wp-content/uploads/2019/10/f410afea8b23fa401505a1449a41a133.png',
                'http://www.nnzhp.cn/wp-content/uploads/2019/11/481b5135e75c764b32b224c5650a8df5.png',
                'http://www.nnzhp.cn/wp-content/uploads/2019/11/b23755cdea210cfec903333c5cce6895.png',
                'http://www.nnzhp.cn/wp-content/uploads/2019/11/542824dde1dbd29ec61ad5ea867ef245.png']
    
    pool=threadpool.ThreadPool(20) #实例化一个线程池
    reqs=threadpool.makeRequests(down_load_pic,url_list)#分配数据,第一个是函数名,第二个是数据
    # [pool.putRequest(req) for req in reqs] #列表生成式,同下面2行代码
    for req in reqs:
        pool.putRequest(req)
        
    pool.wait() #等待,都执行完才打印end,如果不等待会先打印end
    print('end')
    • 守护线程

    守护线程依赖于主线程,主线程结束,守护线程会立刻结束。

    import threading,time
    
    def down_load():
        time.sleep(1)
        print('运行完了')
    
    for i in range(5):
        t=threading.Thread(target=down_load)
        t.setDaemon(True) #设置子线程为守护线程
        t.start()
    
    print('over')
    • 线程锁

    多个线程操作同一个数据的时候,就要加锁,

    import threading
    
    num=0
    lock =threading.Lock()#申请一把锁
    
    def add():
        global num
        # lock.acquire()#加锁
        # num+=1
        # lock.release()#解锁,如果不加锁后不解锁就会出现死锁
    
        with lock:#简写,用with也会帮你自动加锁,解锁
            num+=1
    for i in range(10): t=threading.Thread(target=add) t.start() while threading.activeCount()!=1: pass print('over:',num)

    二、多进程

    进程使用multiprocessing模块

    import multiprocessing,time
    
    def down_load():
        time.sleep(1)
        print('运行完了')
    
    if __name__ == '__main__': #windows下多进程需要在main下写,否则会报错,mac不需要
    
        for i in range(5):
            p=multiprocessing.Process(target=down_load) #实例化一个进程
            p.start()
    
        while len(multiprocessing.active_children())!=0:
            pass
        print(multiprocessing.current_process()) #查看当前进程
        # print(multiprocessing.cpu_count()) #查看cpu个数
        print('end')
  • 相关阅读:
    剑指offer-整数中1出现的次数
    剑指offer-连续子数组的最大和
    剑指offer-最小的k个数
    剑指offer-数组中超过一半的数字
    剑指offer-二叉搜索树与双向链表
    剑指offer-复杂链表的复制
    剑指offer-二叉树中和为某一值的路径
    剑指offer-二叉搜索树的后序遍历
    Alpha 冲刺 (7/10)
    Alpha 冲刺 (6/10)
  • 原文地址:https://www.cnblogs.com/tata-learning/p/11886563.html
Copyright © 2020-2023  润新知