Python之多进程多线程

Posted 塔塔~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)

 

以上是关于Python之多进程多线程的主要内容,如果未能解决你的问题,请参考以下文章

Python之多任务编程线程

python并发编程之多线程

Python之多进程多线程

python并发编程之多线程守护系列互斥锁生产者消费者模型

python之多线程

python并发编程之多线程基础知识点