iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python多线程即相关理念详解
  • 359
分享到

Python多线程即相关理念详解

2024-04-02 19:04:59 359人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录一、什么是线程?二、开启线程的两种方式1、方式12、方式2三、线程对象的jion方法()四、 补充小案例五、守护线程六、线程互斥锁七、GTL-全局解释器八、验证多线程与多线程运用

一、什么是线程?

线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程。车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一个流水线。所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。

总结进程与线程区别:


'''
进程:资源单位
线程:执行单位
线程才是真正干活的人,干活中需要的资源由线程所在进程提供
每个进程肯定自带一个线程
每个进程内可创建多个线程
'''
'''
开进程:
    申请空间
    拷贝代码
    消耗资源大
开线程:
    同一个进程内创建多个线程,无需上述两种操作,消耗资源相对较小
'''

多线程(即多个控制线程)的概念是,在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间,相当于一个车间内有多条流水线,都共用一个车间的资源。

二、开启线程的两种方式

1、方式1


from threading import Thread
import time
# 方法一
def task(name):
    print('%s is running' % name)
    time.sleep(1)
    print('%s is over' % name)
# 开启线程不需要在main下面执行代码,直接书写就可以
# 但是习惯性的将启动命令写在main下面
t = Thread(target=task, args=('eGon',))
t.start()  # 创建线程的开销非常小,几乎是代码一执行就已经创建了
print('主')
'''

运行结果:
egon is running

egon is over
'''

2、方式2


from threading import Thread
class MyThread(Thread):
    def __init__(self, name):
        # 重写了别人的方法,又不知道别人的方法里有啥,就调用父类的方法
        super().__init__()
        self.name = name
    def run(self):
        print('%s is running' % self.name)
        time.sleep(1)
        print('%s is over' % self.name)
if __name__ == '__main__':
    t = MyThread('egon')
    t.start()
    print('主')
'''

运行结果:
egon is running

egon is over
'''

三、线程对象的jion方法()

看过我讲解进程文章的小伙伴想必都知道jion的功能,线程的jion方法于进程的jion方法功能类似-等待一个线程执行完毕后再执行下一个线程


from threading import Thread
def task(name):
    print('%s is running' % name)
    time.sleep(1)
    print('%s is over' % name)
if __name__ == '__main__':
    t=Thread(target=task,args=('egon',))
    t.start()
    t.join()# 主线程等待子线程运行结束后再执行
    print('主')

'''
运行结果:
egon is running
egon is over

'''

补充一个知识点:同一个进程下的多个线程数据共享,下面为大家举一个简单的案例


from threading import Thread
money=100
def task():
    global money
    money=66
if __name__ == '__main__':
    t=Thread(target=task,args=())
    t.start()
    print(money)

# 结果:66

四、 补充小案例


from threading import Thread
import os,time
def task():
    print('子 pid:',os.getpid())
if __name__ == '__main__':
    t=Thread(target=task,args=())
    t.start()
    print('主 pid:',os.getpid())
    # 两个线程的pid号一样,说明在同一个进程下

'''
运行结果:
子 pid: 13444
主 pid: 13444
'''


# 这是个容易混淆的案例
from threading import Thread,current_thread,active_count
import os,time
def task(n):
    print('子',current_thread().name)
    time.sleep(n) # 延长线程存活时间
if __name__ == '__main__':
    t=Thread(target=task,args=(1,))
    t1=Thread(target=task,args=(1,))
    t.start()
    t1.start()
    t.join()
    # print('主',current_thread().name)# 获取线程名字
    print(active_count()) # 统计当前活跃的进程数

'''
运行结果:
子 Thread-1
子 Thread-2
1
'''
# 这里大家容易以为是3,其实运行后只有一个线程在活跃了,其它两个线程运行完后就停止运行了

五、守护线程

守护线程与守护进程的概念也类似,其实大家也能注意到,进程与线程有许多知识点即用法都是相通的,理解了一个另一个也是差不多的道理

1、守护线程会随着主线程的结束而结束

2、主线程运行结束后不会立刻结束,会等待所有的其它非守护线程结束后才会结束

3、因为主线程的结束意味着所在进程的结束


from threading import Thread
import time
def task(name):
    print('%s is running'%name)
    time.sleep(1)
    print('%s is over'%name)
if __name__ == '__main__':
    t=Thread(target=task,args=('egon',))
    t.daemon=True #将t设置为守护线程
    t.start()
    print('主')

'''
运行结果:
egon is running

'''


# 稍微有点迷惑性的例子
from threading import Thread
import time
def foo():
    print('1234')
    time.sleep(1)
    print('end1234')
def func():
    print('5678')
    time.sleep(3)
    print('end5678')
if __name__ == '__main__':
    t1=Thread(target=foo,args=())
    t2=Thread(target=func,args=())
    t1.daemon=True # t1设为守护线程,t2为非守护线程
    t1.start()
    t2.start()
    print('主......')

'''
运行结果:
1234
5678主......
end1234
end5678
'''

'''
因主线程会等待非守护线程运行结束后在结束,
所有主线程会等待t2(非守护线程)结束再结束,
'''

六、线程互斥锁

多个线程操作同一份数据的时候,会出现数据错乱的问题

针对上述问题,解决方式就是加锁处理


from threading import  Thread,Lock
import time
money=100
mutex=Lock()
def task():
    global money
    mutex.acquire()
    tmp=money
    time.sleep(0.1)# 模拟网络延迟
    money=tmp-1
    mutex.release()
if __name__ == '__main__':
    t_list=[]
    for i in range(100):
        t=Thread(target=task,args=())
        t.start()
        t_list.append(t)
    for t in t_list:
        t.join()
    print(money)

# 运行结果:0
# 多个人操作同一份数据,数据错乱,加锁处理

七、GTL-全局解释器

相信学python的小伙伴都知道,Python解释器其实有多个版本

  • Cpython
  • Jpython
  • Pypython

但是普遍使用的都是Cpython解释器

在Cpython解释器中GIL是一把互斥锁,用来阻止同一个进程下的多个线程的同时执行

要注意同一进程下的多个线程无法利用多核优势!!!!

想必大家心中也有不少疑惑:pyhon的多线程是不是一点用都没了呢????

因为Cpython中的内存管理不是线程安全的。多线程并不是一无是处的,在遇到多IO操作的时候,多核的优势也会显示不出来,多进程与多线程的效率在该情况下差不了多少,而此时多进程相对浪费资源,多线程更加节省资源

ps:内存管理就是垃圾回收机制:

1、引用计数

2、标记清除

3、分带回收


# GTL-全局解释器
# 重点:1、GIL不是python的特点而是Cpython解释器的特点
#      2、GIL是保证解释器级别的数据的安全
#      3、GIL会导致同一个进程下的多个线程无法同时进行(即无法利用多核优势)
#      4、针对不同的数据还是需要加不同的锁处理
#      5、解释型语言的通病,同一个进程下多个线程无法利用多核优势

多线程是否有用要看具体情况

八、验证多线程与多线程运用场景


# 计算密集型(CPU一直工作,也没有IO)(更适合多进程)
from multiprocessing import Process
from threading import Thread
import os,time
# 多进程情况
def work():
    res=0
    for i in range(0,10000000):
        res*=i
if __name__ == '__main__':
    l=[]
    print(os.cpu_count())# 获取当前计算机CPU核数
    start_time=time.time()
    for i in range(8):# 我计算机是8核
        p= Process(target=work,args=())
        p.start()
        l.append(p)
    for p in l:
        p.join()
    print(time.time()-start_time)

'''
运行结果:
8
2.0726492404937744
'''


# 多线程情况
from multiprocessing import Process
from threading import Thread
import os,time
def work():
    res=0
    for i in range(0,10000000):
        res*=i
if __name__ == '__main__':
    l=[]
    print(os.cpu_count())# 获取当前计算机CPU核数
    start_time=time.time()
    for i in range(8):# 我计算机是8核
        t=Thread(target=work,args=())
        t.start()
        l.append(t)
    for p in l:
        p.join()
    print(time.time()-start_time)

'''
运行结果:
8
3.5790603160858154
'''

# 显然可知:计算密集型更时候多进程


# IO密集型(任务一直有IO)(多线程更合适)
from multiprocessing import Process
from threading import Thread
import os,time
# 多线程
def work():
    time.sleep(1)
if __name__ == '__main__':
    l=[]
    start_time=time.time()
    for i in range(40):
        t=Thread(target=work,args=())
        t.start()
        l.append(t)
    for p in l:
        p.join()
    print(time.time()-start_time)
# 运行结果:1.0205152034759521
# 多进程
from multiprocessing import Process
from threading import Thread
import os,time
def work():
    time.sleep(1)
if __name__ == '__main__':
    l=[]
    start_time=time.time()
    for i in range(40):
        p= Process(target=work,args=())
        # t=Thread(target=work,args=())
        # t.start()
        # l.append(t)
        p.start()
        l.append(p)
    for p in l:
        p.join()
    print(time.time()-start_time)

# 运行结果:5.927189588546753

# 显然可知:IO密集型更适合多线程

总结:

多线程和多进程都各自有各自的优势

并且在后面的项目中通常可以多进程下面再开设多线程

这样的话我们可以利用多核也可以节省资源消耗

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: Python多线程即相关理念详解

本文链接: http://www.lsjlt.com/news/158738.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python多线程即相关理念详解
    目录一、什么是线程?二、开启线程的两种方式1、方式12、方式2三、线程对象的jion方法()四、 补充小案例五、守护线程六、线程互斥锁七、GTL-全局解释器八、验证多线程与多线程运用...
    99+
    2024-04-02
  • Python多线程即相关理念分析
    这篇文章主要介绍“Python多线程即相关理念分析”,在日常操作中,相信很多人在Python多线程即相关理念分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python多线程即相关理念分析”的疑惑有所帮助!...
    99+
    2023-06-21
  • python 类相关概念理解
    目录什么是类,对象,实例,类## 标题变量(类属性),实例变量(实例属性)类变量和类属性的分类类调用实例方法类的封装(enclosure),继承和多态迭代,迭代器(iterator)...
    99+
    2024-04-02
  • Python多线程与多进程相关知识总结
    目录一、什么是进程二、什么是线程三、并发、并行3.1 并发3.2 并行四、多线程适用场景五、Python GIL六、Python多线程、多进程实例:CPU 密集型任务6.1 单线程6...
    99+
    2024-04-02
  • Python多线程详解
    现代计算机CPU物理核心普遍比较多,我们在编写程序时经常会用到多线程技术来提高程序运行的效率。作为python萌新,我在掌握基本语法后就很想摆弄一下python的多线程,使用起来确实很有pytho...
    99+
    2023-09-08
    python
  • C#多线程的相关操作讲解
    一、线程异常 我们在单线程中,捕获异常可以使用try-catch,代码如下所示: using System; namespace MultithreadingOption { ...
    99+
    2024-04-02
  • Python进程/线程/协程相关
    1、获取进程ID。(getpid)os.getpid()2、获取父进程ID。(getppid)os.getppid()3、获取线程ID。(get_ident)(1)、进程内局部标识。import threading threading.ge...
    99+
    2023-01-31
    线程 进程 Python
  • python多线程超详细详解
    python中的多线程是一个非常重要的知识点,今天为大家对多线程进行详细的说明,代码中的注释有多线程的知识点还有测试用的实例。 import threading from thr...
    99+
    2024-04-02
  • Python线程之多线程展示详解
    目录什么多线程?获取活跃线程相关数据总结什么多线程? 多线程,就是多个独立的运行单位,同时执行同样的事情。 想想一下,文章发布后同时被很多读者阅读,这些读者在做的事情‘阅读'就是一...
    99+
    2024-04-02
  • python之线程相关操作
    1.线程: 一个进程可以有多个线程,共享一个进程的资源; 2.进程线程的区别:    进程是资源分配的最小单位,线程是程序执行的最小单位 3.python中线程模块threading, 提供的类: Thread, Lock, Rlock,...
    99+
    2023-01-30
    线程 操作 python
  • 详解Python中的多线程
    目录什么是多线程:threading模块守护线程与join方法线程锁(互斥锁Mutex)GIL VS LockRLock(递归锁)Semaphore(信号量)Event(事件)生产者...
    99+
    2024-04-02
  • python多线程方法详解
    处理多个数据和多文件时,使用for循环的速度非常慢,此时需要用多线程来加速运行进度,常用的模块为multiprocess和joblib,下面对两种包我常用的方法进行说明。 1、模块安...
    99+
    2024-04-02
  • python 多进程和多线程使用详解
    目录进程和线程 Python的多进程 进程池 多进程间的数据通信与共享 Python的多线程 多线程间的数据共享 使用queue队列通信-经典的生产者和消费者模型进程和线程 进程是...
    99+
    2024-04-02
  • Python多线程编程入门详解
    目录一、任务、进程和线程任务进程线程进程和线程的关系二、Python既支持多进程,又支持多线程Python实现多进程Process进程类的说明Python实现多线程线程类Thread...
    99+
    2024-04-02
  • 怎么理解Python多线程
    本篇内容主要讲解“怎么理解Python多线程”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解Python多线程”吧!在实际处理数据时,因系统内存有限,我们不可能一次把所有数据都导出进行操作...
    99+
    2023-06-25
  • 深入理解python多线程编程
    进程 进程的概念: 进程是资源分配的最小单位,他是操作系统进行资源分配和调度运行的基本单位。通俗理解:一个正在运行的一个程序就是一个进程。例如:正在运行的qq、wechat等,它们都...
    99+
    2024-04-02
  • Python3多线程详解
    目录为什么要使用多线程?如何创建和执行一个线程方法一正式介绍threading模块守护线程 Daemon方法一方法二让主线程等待子线程结束 join线程共享资源可能引起什么问题?竞态...
    99+
    2023-05-19
    Python3多线程 Python3线程
  • 分析详解python多线程与多进程区别
    目录1 基础知识1.1 线程1.2 进程1.3 两者的区别2 Python 多进程2.1 创建多进程方法1:直接使用Process方法2:继承Process来自定义进程类,重写run...
    99+
    2024-04-02
  • Python多线程编程之threading模块详解
    目录一、介绍二、Python如何创建线程2.1 方法一:2.2 方法二:三、线程的用法3.1 确定当前的线程3.2 守护线程3.3 控制资源访问一、介绍 线程是什么?线程有啥用?线程...
    99+
    2024-04-02
  • 详解python字符串相关str
    目录1:访str单个字符2: 字符串连接3:str切片4:使用in 和not in 测试字符串5:str方法6:重复操作符7:分割字符串总结1:访str单个字符 #for循环迭代 n...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作