进行多线程并发测试的过程。
更新时间为2025年05月27日15点25分35秒, 作者是姑娘别秃头。
这篇文章主要的内容是介绍了关于多线程并发的测试过程, 这样的资料是具有非常好的参考价值的, 希望能够帮助到大家, 如果文章中存在错误或没有考虑完全的情况, 希望读者能够不吝赐教。
一、并发和并行, 这两个概念到底有什么区别呢。
1、所谓的多任务这个概念, 指的是操作系统具备同时运行多个任务的能力。
2、关于并发, 它指的是任务的数量超过了cpu的核数这种情况。借助操作系统的任务调度算法,多个任务可以同时执行。实际情况是, 总有部分任务不能同时进行。原因是任务切换的速度极快。从宏观视角来看, 这些任务是并行处理的。从微观视角来看, 并不是所有任务都在同时运行。
3、所谓并行, 它指的是任务的总数量要少于处理器的核心数量这种情况。在这种情况下, 任务们是真正地同步在一块儿执行工作的。
多线程它们其实都是一种并发的状态。这样做有一个缺点, 就是它运行的速度会比并行要慢一些。
二、关于同步与异步的概念是什么?
1、所谓的同步, 就是在行动步调方面实现协同一致。
def work():print("1")
def work2():
print("2")
if __name__ == '__main__':
work()
work2()
2、所谓异步, 指的是事物的运行节奏或者步骤各不相同。
三、我们需要去搞清楚, 线程和进程之间到底存在着什么样的区别?
1、线程是存在于进程内部的组成部分, 当启动一个程序的时候系统会先启动对应的进程, 然后由这个进程去调用相关的线程来具体地执行各种任务。
2、线程这个东西, 它其实是依赖进程而存在的。
3、这个线程是允许被抢占的, 换句话说, 也可以说这个线程会被突然中断。
需求是, 要使用多线程来分别执行那些不同的任务。
1、函数
它是通过这样的一种函数式方法来实现的, 也就是说, 要去调用那些存在于模块内部的括号函数来完成新线程的产生工作。
thread.start_new_thread ( function, args[, kwargs] )参数说明:
主任务在执行的时候, 不会去管那些被它分出去的副任务是不是已经干完了。
import time
import threading as td
#为线程定义一个函数
def asr_test1(url):
print("start")
print(time.ctime(time.time()))
def asr_test2(url):
print("end")
print(time.ctime(time.time()))
if __name__ == '__main__':
#target为函数名,args为元组,函数一定要输入形参
t1=td.Thread(target=asr_test1,args=("",))
t2 = td.Thread(target=asr_test1, args=("",))
t1.start()
t2.start()
结果:
start
Fri Aug 5 16:03:05 2022
start
Fri Aug 5 16:03:05 2022
示例2、主线程等待子线程执行完毕
import threading as th
def work():
print("1")
def work2():
print("2")
#原理:启动时会调用python进程,进程调用主线程。
if __name__ == '__main__':
'''子线程启动'''
start_time = time.time()
t1=th.Thread(target=work)
t2 = th.Thread(target=work2)
t1.start()
t2.start()
#主线程不会等待
# t1.join(5)#设置主线程等待子线程的执行时间
end = time.time() - start_time
print(end)
为程序员提供了那些非常底层的、最为原始的关于线程操作的API, 并且同时也提供了一个相对简单的锁功能。
该类所提供的方法如下所述。
2、类包装线程对象
需求2:多线程执行相同任务
1.并发性
线程是并发运行的, 同时各个线程之间会共享内存。
相关的程序代码展现如下, 其包含重写run方法以及继承类的内容。
import timefrom threading import Thread
'''
Thread其他初始化参数:
target:指定任务函数
name:指定线程分组
'''
class MyThread(Thread):
def run(self):
for i in range(100):
time.sleep(0.1)
print("请求第{}次".format(self.name,i))
if __name__ == '__main__':
for i in range(5):
t=MyThread(name=f"线程{i+1}")
t.start()
首先, 我们要将第一个参数进行传递。
def work(name,age):for i in range(5):
# time.sleep(1)
print("{}work1----{}---{}".format(name,i,age))
if __name__ == '__main__':
#给任务函数传递参数,方式一:args参数,里面是元组
# t=Thread(target=work,args=("",))
# t.start()
#方式2:kargs
t2 = Thread(target=work, kwargs={"name":"wupig","age":18})
t2.start()
把参数进行传递, 让继承类来获取。
2.在多线程运行的那个环节里面, 大家去共享同一个资源, 就容易出现各种因为竞争这个资源而产生的各种各样的问题。
1、它无法以并行的模式来运行, 其核心原因是存在全局解释器锁, 也就是GIL这个因素在里面搞鬼, 因为同一时间段内只能够有一个线程真正地在执行操作, 所谓的通过多线程方式来达成的其实是并发效果, 这种状态在经过了解释器的处理环节之后, 会进入到线程调度的流程里面去, 而关于线程切换的具体机制是怎样的呢。
2、线程在运行过程中遭遇了会耗费大量时间的输入输出操作, 比如睡眠、网络输入输出或者是文件输入输出。这时候解释器会把锁释放掉, 然后进行线程之间的切换去执行其他任务, 待之后再次尝试获取那个全局锁的时候才能继续往下走。
3、线程执行时间达到一定的阈值(面试)
采取第一种处理办法, 那就是为代码加上锁。
解决方法二:队列
死锁案例:
需求:
1、我们来进行并发读取本地文件的操作。
2、通过并发的方式获取到对应的url地址信息。
在xxx.txt这个文件内部是存在非常多URL地址的情况的, 因此当前的需求是针对这些地址进行多并发获取操作。
'''需求:并发读取txt中的URL地址'''list_test=[]
filename="../../url.txt"
file=open(filename,"r")
#列表推导式
list_test=[i.strip("\n") for i in file]
def audio_test():
while list_test:
url=list_test.pop()
print(url)
def atest_thread(THREAD_MAX, Test_Script):
#创建空列表
thread_list = []
for i in range(int(THREAD_MAX)):
# print("**************",i)
thread_name = 'thread-' + str(i)
print("thread_name",thread_name)
new_thread = threading.Thread(target=Test_Script, args="", name=thread_name)
thread_list.append(new_thread)
new_thread.start()
for thread_obj in thread_list:
#thread_obj.join:等待至线程中止
thread_obj.join()
if __name__ == '__main__':
starttime=time.time()
count = 10
# THREAD_MAX=10
atest_thread(count, audio_test)
endtime=time.time()-starttime
print(endtime)
占坑
这种情况就只剩下了一个线程在执行任务了。我们需要去创建一个列表, 接着把线程放进这个列表里面去, 然后去对列表进行循环遍历的操作, 这样来对JSON数据进行相关的处理。
总结
上面的内容都是我自己的一些经验之谈, 希望能够给到大家提供一个具有参考价值的意见, 同时也希望大家能够多多地去支持脚本之家这个平台。