今天有一名测试的小伙伴问我,在遇到程序限制的每天点赞次数和每天限制的播放量该怎么测试呢,这种往往需要操作上万次才能测试验证的光靠人力肯定无法实现的。遇到这种问题靠人力肯定是不行的用程序的话循环上万次甚至十几万次几十万次肯定也是最不理想的实现方式,这时候就要用到我们的多线程,多进程技术了。
首先来大致说明一下什么是进程什么是线程。进程是资源单位,每个进程至少有一个线程,线程呢又是执行单位,每启动一个进程都会存在一个默认的主线程。这样说可能有一点点抽象,我们可以把进程想象成一家公司,既然是公司肯定会存在一定的业务一定的事情等着人去做,而线程就可以想象成公司里的人体的员工去做某个具体的事情。
如何创建线程:
这里创建两个线程:
from threading import Thread # 线程类
def func(name):
for i in range(1000):
print(name, i)
if __name__ == '__main__':
t1 = Thread(target=func, args=('线程1:',))
t2 = Thread(target=func, args=('线程2:',))
t1.start() # 开始执行该线程,该线程可以开始工作,具体什么时候执行看cpu决定
t2.start()
当然创建线程还有另一种写法:
class MyThread(Thread): # 继承多线程的方法
def run(self):
for i in range(1000):
print('子进程', i)
if __name__ == '__main__':
t = MyThread()
t.start()
创建线程池:
首先我们要了解一下什么是线程池,当我们创建大量线程,线程的集合就叫线程池,哈哈哈。使用线程池可以很好的提高系统的性能,线程池启动时会立刻创建大量的空闲线程,程序将大量任务传给线程池,此时线程池就会使用空闲的线程来执行这个任务,当这个任务执行结束后线程又会回到线程池中成为空闲线程,等待下一个任务。当然一个线程只能执行一个任务,程序会向线程池一下子提供多个任务去执行。
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
def fn(name):
for i in range(100):
print(name, i)
if __name__ == '__main__':
# 创建线程池
with ThreadPoolExecutor(50) as t:
for i in range(100):
t.submit(fn, name=f'线程:{i}')
# 等待线程池中任务全部执行
print('123')
多进程跟多线程相比一般使用的频率会小很多,因为多进程是很耗资源的。其实写法跟多线程是一样的。
from multiprocessing import Process
def func():
for i in range(1000):
print('子进程', i)
if __name__ == '__main__':
p = Process(target=func)
p.start()
for i in range(100):
print('主进程', i)
这是一个直接可以运行的例子,上面很多关于requests库的的方法这里就不重复讲了
import threading:引入线程组模块
threads = []:创建线程组用于装载线程
threading.Thread():通过调用threading模块的Thread()方法来创建线程。Thread()可以加入参数target=需要加入线程的方法名、args=该方法需要传入的实参没有则不写。
from time import sleep,ctime
import requests
import threading
class Requestuil:
def __init__(self):
pass
def request(self,url,method,headers=None,param=None,content_type=None):
'''请求工具类封装'''
try:
if method == "get":
result = requests.get(url=url,params=param,headers =headers).json()
return result
elif method == "post":
if content_type == "application/json":
result = requests.post(url=url,json=param,headers = headers).json()
return result
else:
result = requests.post(url = url,data=param,headers=headers).json()
return result
else:
print('只做了post and get请求')
except Exception as e:
print("http请求报错:{0}".format(e))
if __name__ == '__main__':
r = Requestuil()
url = 'http://app.ppmbook.com/book/addHeat.do'
heard = {'token':'d57c1c60e6709396382c9a5e3652075674054e6ee4cc6f8db407b5ec64ae34c810a07b61b15b6554d449de10df4bb1fb',
'oid':'01fe710d81d3439aabbcda4483f607fc'}
param = {'inParam':'{"mediumId":7665,"oid":"01fe710d81d3439aabbcda4483f607fc"}'}
'''播放一百次测试'''
def play():
for i in range(100):
print(r.request(url=url,method='post',headers=heard,param=param))
sleep(1)
urlxq = 'http://app.ppmbook.com/book/viewBookNew.do'
'''查看详情页100次测试'''
def details():
for i in range(100):
print(r.request(url=urlxq,method='post',headers=heard,param=param))
sleep(1)
threads = []
t1 = threading.Thread(target=play)
threads.append(t1)
t2 = threading.Thread(target=details)
threads.append(t2)
for t in threads:
t.start()
for t in threads:
t.join()
通过for循环遍历threads数组中所装载的线程,start()开始线程活动,join()等待线程终止。
看,两个线程是同步执行的,这样可以大大减少代码执行的时间