python开发-多线程利用及原理

前言

在利用python开发的时候总会遇到各种需要处理的批量任务,如果任务量过大就会造成时间的占用,这就很不舒服了,为了解决这种情况的发生,我将使用threading模块进行讲解它的使用及原理,解决我们为什么要使用多线程,多线程该又如何使用?
另外不懂模块和代码的可以自行在网上去搜索,这里只讲利用及原理,不是讲解代码

原理

在一个程序中运行的两个线程也意味着它们几乎同时运行,为什么说是同时,执行多线程程序的时候给人感觉就是同时运行,其实不是。这涉及到了一个"并发"的术语:不同的代码交替执行

线程是什么?线程是进程的一个组件。也就是说运行多线程的时候和进程的处理几乎不会有关系。因为在进程的处理有个叫CPU限制的术语,它是用来处理任务或程序的执行。而而线程并不会受到CPU限制的影响,但是使用多线程技术只适用于I/O限制。I/O限制是用来处理任务或程序的执行依赖于输入输出系统及其资源(如写入文件,下载资源)。

代码演示

导入多线程模块中的 Thread模块,和时模块。该代码用来测试输出的字符然后再睡眠两秒,我们利用多线程给技术看一看它花了多少时间。

from threading import Thread
import time

start  = time.perf_counter()
num = 13

def flag():
    print('你的幸运数是'+str(num))
    time.sleep(2)
    print('end of sleep!!!')    

threads = []

if __name__ =='__main__':
    print("我将打印喜欢幸运数的次数为十次")
    for _ in range(10):
        t = Thread(target=flag)
        t.start()
        threads.append(t)    
        
    for thread in threads:
        thread.join()

finish = time.perf_counter()
print(f'程序所花实际为{round(finish-start,3)}')

运行py文件之后,可以看见程序运行花费的时间几乎为2秒,这也应证了前面所说的原理,这里也不在解释了。

在这里插入图片描述

为了让大家理解代码的含义,这里也将说明以下该代码在做什么功能又是什么?

定义一个开始的变量放入运行程序自定义函数之前是为了严谨的证明,运行之前所花费的时间。其中time.perf_counter()意思为返回性能计数器所运行时间的值,默认以秒为单位,不过它是浮点型,输出的时候要表示它是浮点型。

start  = time.perf_counter()

自定义函数flag,可以看见输出幸运数后睡眠了两秒,运行程序之后发现只花费了2秒就输出了10次幸运数,期间输出之后睡眠了两秒,因为在多线程的利用下,几乎是同时输出,所以没有花费20秒时间。使用join方法是为了强占子线程完成之后在运行主线程,线程抢占到CPU资源,它就不会再释放,直到线程执行完毕,这是为了精准的计算多线程所使用的时间

def flag():
    print('你的幸运数是'+str(num))
    time.sleep(2)
    print('end of sleep!!!')    

threads = []

if __name__ =='__main__':
    print("我将打印喜欢幸运数的次数为十次")
    for _ in range(10):
        t = Thread(target=flag)
        t.start()
        threads.append(t)    
        
    for thread in threads:
        thread.join()
finish = time.perf_counter()
print(f'程序所花实际为{round(finish-start,3)}')

为了明确区分单线程和多线程的区别,我们将thread函数去除,改为for循环10次执行该flag自定义函数,可以发现程序所花实际为几乎为20秒。

import time

start  = time.perf_counter()

num = 13
def flag():
    print('你的幸运数是'+str(num))
    time.sleep(2)
    print('end of sleep!!!')    

threads = []

if __name__ =='__main__':
    print("我将打印喜欢幸运数的次数为十次")
    for _ in range(10):
        flag()   
        
    for thread in threads:
        thread.join()

finish = time.perf_counter()
print(f'程序所花实际为{round(finish-start,3)}')

在这里插入图片描述

总结

所以说多线程技术只能用于I/O任务的方向,例如写入磁盘、等待网络资源等。如果你的代码是用于处理cpu进程任务,那不应该使用线程,因为这涉及到了GIL,而且也不是I/O任务。前面简单的案例也证明了处理多线程处理I/O任务的快捷的必要性。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cike_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值