python:多线程实现API并发测试

import requests
import threading
import time

data = {
	"times": 20, # 并发量
	#"method": "POST",
	"url": "http://www.baidu.com",
	"header": {
		#header
	},
	"body": {
		#参数
	}
}


def get_requests():
	global RIGHT_NUM
	global ERROR_NUM
	try:
		r = requests.get(data["url"],headers = data["header"])
		#print(r.status_code)
		if r.status_code == 200:
			RIGHT_NUM += 1
			#print("RIGHT_NUM:",RIGHT_NUM)
		else:
			ERROR_NUM += 1
	except Exception as e:
		print(e)

def run1():
	Threads = []
	time1 = time.process_time()
	for i in range(data["times"]):
		t = threading.Thread(target = get_requests)
		t.setDaemon(True)
		Threads.append(t)

	for t in Threads:
		t.start()
	for t in Threads:
		t.join()

	time2 = time.process_time()

	print("===============测试结果===================")
	print("URL:", data["url"])
	print("并发数:", data["times"])
	print("总耗时(秒):", time2 - time1)
	print("每次请求耗时(秒):", (time2 - time1) / data["times"])
	print("正确数量:", RIGHT_NUM)
	print("错误数量:", ERROR_NUM)


if __name__ == '__main__':

	RIGHT_NUM = 0
	ERROR_NUM = 0
	print('测试启动')

	run1()

	print("执行结束.")

问题:

1.对于print("正确数量:", RIGHT_NUM)时,若之前没有调用t.join(),输出的RIGHT_NUM是0,join() 是保证thread子线程执行完毕后才能执行下一个线程,对于join()的用法如下几个例子:

#没有join()函数,线程执行顺序不定,主线程可能在所有子线程执行完之前就执行了
def test(p):
    time.sleep(0.001)
    print(p)
 
ts = []
 
for i in range(15):
    th = threading.Thread(target=test, args=[i])
    ts.append(th)
 
for i in ts:
    i.start()
 
print("it is end !")
 
#输出 
0
1
it is end !
4
2
3
5
#修改代码如下:每次启动一个子线程后,调用一次join()函数,可以看出线程按顺序执行,
#且主线程在所有子线程执行完之后才执行。
for i in ts:
    i.start()
    i.join()   #join()使i线程跑完后才能继续跑下一个子线程
 
 
print("it is end !")
 
 
#输出 
0
1
2
3
4
5
it is end !
#修改代码如下:可以看出子线程执行顺序不定,但是主线程是在所有子线程执行完毕之后才执行的。
for i in ts:
    i.start()
 
# 此处的join()使子线程全部跑完再继续往下跑主线程
for i in ts:
    i.join()
 
print("it is end !")
 
#输出
1
0
4
5
2
3
it is end !

 2.对于threading.Thread(target ,args)的参数target是线程指定要执行的代码,args指定该代码的参数。其中,target的函数名不能带括号,否则就会由主线程执行。

t = Thread(target=fun, args=(10,))   #args的逗号不能省略
t = Thread(target=fun(), args=(10,))    #不能带括号

两种情况有可能看似最终结果是一样的,但实际上并不是线程并发执行,例如,最上面的并发测试代码把get_requests()里注释去掉,可以看出两种情况的不同执行过程,如下:

#t = threading.Thread(target = get_requests)的情况下执行结果
测试启动
200
RIGHT_NUM: 1
200
RIGHT_NUM: 2
200
RIGHT_NUM: 3
200
200
200
RIGHT_NUM: 6
RIGHT_NUM: 4
RIGHT_NUM: 5
200
RIGHT_NUM: 7
200
RIGHT_NUM: 8
200
RIGHT_NUM: 9
200
RIGHT_NUM: 10
===============测试结果===================
URL: http://www.baidu.com
并发数: 10
总耗时(秒): 0.041579000000000005
每次请求耗时(秒): 0.004157900000000001
正确数量: 10
错误数量: 0
执行结束.
#t = threading.Thread(target = get_requests())的情况下执行结果
测试启动
200
RIGHT_NUM: 1
200
RIGHT_NUM: 2
200
RIGHT_NUM: 3
200
RIGHT_NUM: 4
200
RIGHT_NUM: 5
200
RIGHT_NUM: 6
200
RIGHT_NUM: 7
200
RIGHT_NUM: 8
200
RIGHT_NUM: 9
200
RIGHT_NUM: 10
===============测试结果===================
URL: http://www.baidu.com
并发数: 10
总耗时(秒): 0.04643899999999998
每次请求耗时(秒): 0.004643899999999998
正确数量: 10
错误数量: 0
执行结束.

 

你可能感兴趣的:(测试)