python多线程和异步性能对比_python并发和性能(进程,线程,协程,队列)

本文深入探讨了并发和并行的概念,介绍了单核CPU如何通过任务调度实现多任务执行。接着,详细阐述了线程、并发、并行、同步和异步的区别,通过实例展示了Python中多线程的实现,包括创建线程、线程同步与互斥锁。此外,文章还讨论了全局解释器锁(GIL)对Python多线程的影响。最后,通过队列和协程展示了进程间通信以及并发执行的优化策略,强调了协程在资源消耗和执行效率上的优势。
摘要由CSDN通过智能技术生成

一、并发和并行

1、多任务

多任务的概念

简单的说,就事操作系统可以同时运行多个任务

CPU与多任务的关系:

单核CPU可不可以多任务?

也可以执行多任务,由于CPU执行代码都是顺序执行的,那么单核CPU是怎么执行多任务的呢?

答案就是操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,在切换到任务3,执行0.01秒.......这样反复下去,表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。

真正的并行执行多任务只能在多核CPU上实现,但是由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把多任务轮流调度到每个核心上执行。

2、并发和并行

并发: 指的是任务数多于CPU核数,通过操作系统的各种任务调度算法,实现用多任务“一起”执行(实际上总有一些任务不在执行,因为切换任务的速度相当快,看上去一起在执行而已)

并行: 指的是任务数小于等于CPU核数,即任务真的在一起执行的

并发

并行

3、同步和异步

同步(同步协调): 是指线程在访问某一资源时,获得了资源的返回结果之后才会执行其他操作,(先做某件事,再做某件事)

异步: 与同步相对,是指线程再访问某一资源时,无论是否取得返回结果,都进行下一步操作;当有了资源返回结果时,系统自会通知线程。

二、线程

问题:

当前有两件事情,做事情1需要5秒,做事情2需要6秒

def func1():

for i in range(5):

print("-----正再做事情1------")

time.sleep(1)

def func2():

for i in range(6):

print("-----正再做事情2------")

time.sleep(1)

单任务

先做事情一

在做事情二

多任务

两个事情同时做

怎么才能同时做呢?

多线程执行

1、Threadting模块介绍

Python的_thread模块是比较底层的模块,Python的threading模块是怼thread模块做了一层包装的,可以更加方便的使用

创建多线程:threading.Thread(target=func1)

参数target指定线程执行的任务(函数)

Thread类提供了以下方法

run() :用以表示线程活动的方法

start() :启动线程活动

join(timeout) :等待子线程的方法,默认等待子线程执行结束

lsAlive() :返回线程是否活动的

getName() :返回线程名

setName() :设置线程名

threading提供的以下方法

threading.current_thread() :返回当前执行的线程

threading.enumerate() :返回正在运行的所有线程(list)

threading.active_count() :返回正在运行的线程数量

2、多线线程实现多任务

利用threading模块实现

import threading

import time

def fun_1():

for i in range(5):

print("线程{}:{}".format(threading.current_thread(), i))

time.sleep(1)

def fun_2():

for i in range(6):

print("线程{}:{}".format(threading.current_thread(), i))

time.sleep(1)

def main():

# 建立线程1 执行函数1

t1 = threading.Thread(target=fun_1, name="th_1")

# 建立线程2 执行函数2

t2 = threading.Thread(target=fun_2, name="th_2")

s_time = time.time()

# fun_1()

# fun_2()

# 设置名字

t1.setName("TH_1")

print(t1.getName())

# 开始

t1.start()

t2.start()

# 查看线程集合,和线程数

print(threading.enumerate())

print(threading.active_count())

# 等待子线程执行完毕

t1.join()

t2.join()

e_time = time.time()

print("时间:", e_time - s_time)

if __name__ == '__main__':

main()

重写run方法实现多线程

线程启动start方法就是运行了run方法

通过继承Thread类,重写run方法,来创见线程

创建线程时不需要在传任务函数

如果任务函数需要参数,需要重写init方法,并返回父类init方法

import threading

import time

import requests

# 计算时间装饰器

def add_time(fun):

def inner(*args):

start_time = time.time()

fun(*args)

end_time = time.time()

print("---------------线程:{},执行时间:{}-----------------".format(threading.current_thread(), end_time - start_time))

return end_time - start_time

return inner

# 重写run方法创建多线程

class RequestThread(threading.Thread):

def __init__(self, url):

self.url = url

super().__init__()

@add_time

def run(self):

for i in range(100):

res = requests.get(self.url).status_code

print("线程{}得执行结果为:{}".format(threading.current_thread(), res))

@add_time

def main():

t_list = [] # 线程列表

# 建立线程

for i in range(10):

t = RequestThread("http://httpbin.org/post")

t_list.append(t)

# 开启线程

for th in t_list:

th.start()

# 等待线程结束

for th in t_list:

th.join()

if __name__ == '__main__':

total_time = main()

print("每个接口平均时间:", total_time / 1000)

3、多线程-共享全局变量

问题:1000000次的bug

两个线程完成对全局变量的2百万次修

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值