python--多线程--多进程--单元测试

夙愿已清 提交于 2019-12-05 00:38:31

一、self的作用

class Person:    country = 'China'    def __init__(self,name):        self.name = name        print('内存地址',id(self))    def say(self):        print(self.name)xm = Person('小明')print('xm的内存地址',id(xm))xm.say()xh = Person("小红")print('xh的内存地址',id(xh))xh.say()每次实例化的是谁,self 就是谁

 

二、多线程

import threadingimport time#进程是多个资源的集合。#线程是就是进程里面具体干活的。#线程和线程之间是互相独立的。def down_load():    time.sleep(5)    print("运行完了")def movie():    time.sleep(1)    print('movie')
# threading.Thread(target=down_load,args=('name','abfd'))#启动线程 ,target=函数名,args=(参数1,参数2)
t1 = threading.Thread(target=down_load)t1.start()t2 = threading.Thread(target=down_load)t2.start()t3 = threading.Thread(target=down_load)t3.start()

启动多个线程可以使用for循环的方式

for i in range(10):    t = threading.Thread(target=down_load)    t.start()

 

 

 

 

 

 

 

start_time = time.time()for i in range(10):    t = threading.Thread(target=down_load)    t.start()for i in range(5):    t = threading.Thread(target=movie)    t.start()end_time = time.time()print(end_time - start_time)

没有等子线s程执行完,时间直接打印出来,因为线程和线程之间是独立的,这里统计的只是主线程(最开始执行的线程)运行的时间,通过主线程启动的线程叫做子线程

print('当前线程数',threading.activeCount()) #查看当前线程数

 


 统计所有子线程运行完所用的时间,

方式1:用.join()

start_time = time.time()for i in range(5):    t = threading.Thread(target=movie)    t.start()    t.join()#end_time = time.time()print(end_time - start_time)print('当前线程数:',threading.activeCount()) #查看当前线程数print('当前线程',threading.current_thread())#查看当前线程

 


 方式二:

start_time = time.time()thread_list = []for i in range(5):    t = threading.Thread(target=movie)    t.start()    thread_list.append(t)print('thread_list',thread_list)#for thread in thread_list:    thread.join() #主线程等待子线程结束end_time = time.time()print(end_time - start_time)

 

 

 方式三、

start_time = time.time()for i in range(5):    t = threading.Thread(target=movie)    t.start()while threading.activeCount()!=1:    passprint('当前线程数',threading.activeCount()) #查看当前线程数print(threading.current_thread())#查看当前线程end_time = time.time()print(end_time - start_time)

 


2.1、下载图片例子,查看串行和并发的速度

import requests,time,threadingfrom hashlib import md5result_list = {}def down_load_pic(url):    req = requests.get(url)#请求下url    m = md5(url.encode())#将url md5下,当文件名    file_name = m.hexdigest()+'.png'    with open(file_name ,'wb') as fw:#打开文件        fw.write(req.content)    # return file_name    result_list[file_name] = threading.current_thread()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,))#args=(url,)#只有一个参数,一定要加个逗号    t.start()while threading.activeCount()!=1:    passend_time = time.time()print(end_time - start_time)print(result_list)

 

#有时候多线程速度不一定会快,没有真正意义上的并发,CPU有几个核心就只能同时运行几个任务(线程),因为CPU运行速度快,让你感知多线程是同时进行的
#4c,假如电脑是4核,同时支持4个任务一起运行,但是python 只能运行1cpu,其他的用不了,python的多线程不是真正的多线程,因为python语言设计问题是GIL全局解释器锁导致的,有的线程运行速度快,有点用的慢,数据可能会丢失#cpu 上下文切换,让python看起来是并发,cpu只负责调度任务,存储是在磁盘上进行的。cpu完成一个调度任务就去执行下个任务

#多进程#CPU有几个核心就只能同时运行几个任务(线程)2.2、异步任务
import yagmail,threadingdef send_mail():    smtp = yagmail.SMTP(host='smtp.163.com',                        user='**@163.com',                        password='****'                        )    smtp.send(to='**@163.com',cc=['****@163.com','***@qq.com'],subject='标题',              contents='正文',attachments=[r'/Users/nhy/PycharmProjects/mjz/day6/jsonpath模块.py']              )def async_send_mail():    t = threading.Thread(target=send_mail)#启动线程发邮件    t.start()
 
2.3、线程池
import threadpoolimport requests,time,threadingfrom hashlib import md5def down_load_pic(url):    print(threading.current_thread())    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]#列表生成式# for req in reqs:#     pool.putRequest(req)print(threading.activeCount())pool.wait() #等待print('end')

 


 

2.4、守护线程
#主线程结束,守护线程立马死掉。import threading,timedef down_load():    time.sleep(5)    print("运行完了")for i in range(10):    t = threading.Thread(target=down_load)    t.setDaemon(True) #设置子线程为守护线程    t.start()print('over')

七、锁
#多个线程操作同一个数据的时候,就得加锁import threadingnum = 0lock = threading.Lock() #申请一把锁def add():    global num#修改全局变量要加global声明    lock.acquire()#加锁    num+=1    lock.release()#解锁  加锁后不解锁会导致死锁for i in range(20):    t = threading.Thread(target=add,)    t.start()while threading.activeCount() !=1:    passprint(num)

 

 

 

'''用with方式替代加锁解锁'''
#多个线程操作同一个数据的时候,就得加锁import threadingnum = 0lock = threading.Lock() #申请一把锁def add():    global num#修改全局变量要加global声明        with lock:#简写,用with也会帮你加锁,解锁        num+=1for i in range(20):    t = threading.Thread(target=add,)    t.start()while threading.activeCount() !=1:    passprint(num)

 

 

 3、多进程

import multiprocessing,timedef down_load():    time.sleep(5)    print("运行完了")if __name__ == '__main__':#windows 电脑必须使用这个不会报错
    for i in range(5):        p = multiprocessing.Process(target=down_load)        p.start()    print(multiprocessing.current_process())    print('进程数',multiprocessing.active_children())    print('cpu 数量',multiprocessing.cpu_count())    print('end')

import multiprocessing,timedef down_load():    time.sleep(5)    print("运行完了")if __name__ == '__main__':#windows 电脑必须使用这个不会报错    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.active_children())    print('cpu 数量',multiprocessing.cpu_count())    print('end')

 

 

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

input/output
网络io:网络上传下载内容
磁盘io:数据库存文件
多进程:
适用于CPU密集型任务:排序,计算

#多进程内也可以启动几个线程,因为进程里干活的实际是线程

 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!