python_多线程多进程

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

IO,input,output缩写,包括网路io(比如上传下载),磁盘io,(比如数据库读写),CPU操作不频繁

 

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

数据分析,算法,依赖CPU来运算

 

进程就是多个资源的集合,

线程是包含在进程里面的,线程和线程直接是相对独立的

线程的优点

1.易于调度。

2.提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。

3.开销少。创建线程比创建进程要快,所需开销很少。

4.利于充分发挥多处理器的功能。通过创建多线程进程,每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。
def down_load():
    time.sleep(5)
    print('运行完了')
# threading.Thread(target=down_load,args=('name','id')#target是函数名,args是函数的参数没有可以不写
t1 = threading.Thread(target=down_load)
t1.start()#启动线程

每个子线程都是在主线程里启动的子线程

======================================================================================

继承调用

class Test_thread(threading.Thread):#继承threading的Thread类
    def __init__(self,num):
        threading.Thread.__init__(self)#执行父类的构造方法
        self.num = num
    def run(self):#运行多线程的函数
        while self.num>0:
            print(threading.active_count())#打印当前线程数量
            self.num-=1
for i in range(5):
    t = Test_thread(2)#生成实例
    t.start()#启动线程

Python不是真正意义的多线程,Python代码的执行由Python 虚拟机(也叫解释器主循环,CPython版本)来控制,Python 在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即在任意时刻,只有一个线程在解释器中运行。对Python 虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。CPU有几个核心就能够同时执行几个任务,Python无法利用多核就是因为它有全局解释器锁(GIL)

==================================================================================================

线程池,线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。此外,使用线程池可以有效地控制系统中并发线程的数量。当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致 Python解释器崩溃,而线程池的最大线程数参数可以控制系统中并发线程的数量不超过此数

 

下面是一个下载图片的线程池例子:

import threadpool,requests
from hashlib import md5
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']

def down_load(url):#下载图片的函数
    r = requests.get(url)
    m = md5(url.encode())
    with open(m.hexdigest()+'.png','wb')as fw:
        fw.write(r.content)

pool = threadpool.ThreadPool(10)#实例化一个线程池 threadpool实例化一个对象pool,调用了构造函数参数是10
reqs = threadpool.makeRequests(down_load,url_list)#分配数据

for req in reqs:
    pool.putRequest(req) #将线程放入线程池

# [pool.putRequest(req) for req in reqs]#列表生成试
pool.wait()#等待线程池结束
print('end')#运行主线程

 

=====================================================================================================================

守护线程,主线程结束,守护线程马上死掉

import threading
import time
class Fun():
    def sum(self,a,b):
        time.sleep(2)
        print(a+b)
    def cut(self,c,d):
        time.sleep(5)
        print(c-d)
T = Fun()
t1 = threading.Thread(target=T.sum,args=(1,2))
t2 = threading.Thread(target=T.cut,args=(5,4))
t1.setDaemon(True)#设置线程为守护线程
t2.setDaemon(True)#设置线程为守护线程
t1.start()
t2.start()
print('主线程运行完毕')

结果只会打印出'主线程运行完毕'

===================================================================================================================

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

num = 0
lock = threading.Lock()#申请一把锁

def add():
    global num
    with lock:#加锁,解锁
        num+=1

for i in range(20):
    t = threading.Thread(target=add)
    t.start()

print(num)

 ===================================================================================================================

多进程


import multiprocessing,time
def down_load():
time.sleep(5)
print('运行完了')

if __name__ == '__main__':#windows系统要加,不然会报错

for i in range(5):
p = multiprocessing.Process(target=down_load)#分配5个进程运行函数
p.start()#启动进程
p.join()#等待子进程。子线程互相等待

while len(multiprocessing.active_children())!=0:#等待子进程执行完在执行主进程
pass

print(multiprocessing.active_children())#查看有多少个子进程

print(multiprocessing.current_process())#主进程
 

 

 

 
posted @ 2019-11-22 16:30  小马哥007  阅读(144)  评论(0编辑  收藏  举报