python程序默认执行与多线程

简介:

一、程序执行流程和进程线程简述

1程序执行流程
有类似脚本程序或编程经验的同学都知道,程序默认是自上而下,从左到右的按顺序执行,也叫串行执行;而多线程类似于并行执行,即A模块(函数)执行时B也执行不需要等A执行完再执行,这里请区别对待并发执行(同一时间执行);以上是简单概念性描述,

2什么是线程与进程?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
本节不讨论进程.以下主要说明线程的应用.进程,以及进程与线程,有兴趣可以参考这里

3python中的线程
以下引用廖雪峰博客Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。后面通过示例说明这一点.

     GIL是Python解释器设计的历史遗留问题,通常我们用的解释器是官方实现的CPython,要真正利用多核,除非重写一个不带GIL的解释器。

所以,在Python中,可以使用多线程,但不要指望能有效利用多核。如果一定要通过多线程利用多核,那只能通过C扩展来实现,不过这样就失去了Python简单易用的特点。
不过,也不用过于担心,Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响.

二、python程序执行流程示例

以下示例均在python3.5.2中完成

1、默认执行流程

import time

def Foo():
    sleep(2)
    print("I am Foo.")

def Bar():
    sleep(3)
    print("I am Bar.")

if __name__ == "__main__":
    start = time.time()  #程序执行开始时间
    Foo()
    Bar()
    end = time.time()
    print("程序执行完使用 %s" %(end - start))

执行结果:
python程序默认执行与多线程
可以看出,程序从上而下的调用了Foo函数休眠2秒再执行Bar函数休眠3秒,最后执行完成共使用大约5秒多一点时间.这说明 Foo执行完才执行Bar.

2、线程执行
在讨论线程时,先问一个问题,自上而下的串行执行可以满足条件,为啥要多线程并行去执行?想像一个场景,我们在看一部电影时,要是默认串行执行,先放图像 再放电影中的声音,能接受吗?

def Movie_music(func):
    print(threading.current_thread())
    for i in range(2):
        print("Begin  listening to %s . %s" %(func,ctime()))
        sleep(2)
        print("End listening %s" % ctime())

def Movie_grap(func):
    print(threading.current_thread())
    for i in range(2):
        print("Begin watching at the %s! %s" %(func,ctime()))
        sleep(3)
        print("End watching %s" %ctime())

threads= []
t1 = threading.Thread(target=Movie_music,args=(u"七里香.mtv",))
threads.append(t1)
t2 = threading.Thread(target=Movie_grap,args=(u"七里香.mtv",))
threads.append(t2)

if __name__ == "__main__":
    for t in threads:

        t.start()
    t.join()          
    print("MTV播放结束: %s" %ctime())   

执行结果:
python程序默认执行与多线程
所谓的多线程并不是同一时刻而是在很多的时间内进行了切换,而人的感观只要超过1/12之秒基本等同于同一时间,从上面的started 140049239336704 可以看出纳秒级别,时间上基本是同一秒,所以这首MTV中的音乐和图像 让我感觉 是同时发生的.这就是多线程的好处.如果换成串行播放,那一个五分钟的MTV可能就要10分钟播放完,先放声音或先放图像.

三、什么时候使用python中的多线程

    由于python解释器执行代码时,有一个GIL锁:Global Interpreter Lock的限制,多线程在Python中只能交替执行,即使100个线程跑在拥有100核CPU上,也只能用到1个核。其他核无法在多线程情况下使用.

计算密集型操作之串行

import time
def add(n):
    sum = 0
    for i in range(int(n)):
        sum+=i
    print(sum)
    print("finshed.")

if __name__ == "__main__":
    start = time.time()
    add(100000000)
    add(10000000)
    end = time.time()
    print(end - start)

运行结果:
python程序默认执行与多线程

计算密集型操作之多线程并行执行

def add(n):
    sum = 0
    for i in range(int(n)):
        sum+=i
    print(sum)
    print("finshed.")

if __name__ == "__main__":
    start = time.time()
     t1 = threading.Thread(target=add,args=(100000000,))  #计算密集型
     t1.start()

     t2 = threading.Thread(target=add, args=(10000000,))
    t2.start()

     t1.join()
     t2.join()

    end = time.time()
    print(end - start)

运行结果:
python程序默认执行与多线程

可以看出无论是串行执行还是多线程并行执行,计算结果一样,但花费的时间多线程并没有少于串行执行,反而略多,在python2.x上差距会更多,而上面的例子是IO密集型多线程明显要优于串行.
所以对于IO密集型情况使用多线程比较合适,而对于计算密集型由于python GIL的限制不能真正使用多核,无法提高cpu计算效率,不宜使用多线程.可以采用多进程多线程方式 .










本文转自 dyc2005 51CTO博客,原文链接:http://blog.51cto.com/dyc2005/2044830,如需转载请自行联系原作者
目录
相关文章
|
10天前
|
jenkins 持续交付 Docker
docker之自定义制作镜像(python程序)
docker之自定义制作镜像(python程序)
|
9天前
|
Python
Python 编程入门:打造你的第一个程序
【9月更文挑战第27天】编程,就像是在数字世界里绘画。想象一下,你手中的键盘是画笔,屏幕是画布,而代码则是你的颜料。这篇文章将带你走进编程的世界,学习如何使用 Python 这门语言来创建你的第一个程序。我们将从基础的语法开始,逐步深入到条件判断和循环结构,最终完成一个简单的猜数字游戏。无论你是否有编程经验,这里的内容都将为你打开一扇新的大门。
|
9天前
|
Windows Python
python获取windows机子上运行的程序名称
python获取windows机子上运行的程序名称
|
9天前
|
Python
5-5|python开启多线程入口必须在main,从python线程(而不是main线程)启动pyQt线程有什么坏处?...
5-5|python开启多线程入口必须在main,从python线程(而不是main线程)启动pyQt线程有什么坏处?...
|
12天前
|
负载均衡 Java 调度
探索Python的并发编程:线程与进程的比较与应用
本文旨在深入探讨Python中的并发编程,重点比较线程与进程的异同、适用场景及实现方法。通过分析GIL对线程并发的影响,以及进程间通信的成本,我们将揭示何时选择线程或进程更为合理。同时,文章将提供实用的代码示例,帮助读者更好地理解并运用这些概念,以提升多任务处理的效率和性能。
|
6天前
|
数据采集 Linux 调度
Python之多线程与多进程
Python之多线程与多进程
13 0
|
7天前
|
并行计算 关系型数据库 MySQL
30天拿下Python之使用多线程
30天拿下Python之使用多线程
18 0
|
11天前
|
存储 算法 Java
关于python3的一些理解(装饰器、垃圾回收、进程线程协程、全局解释器锁等)
该文章深入探讨了Python3中的多个重要概念,包括装饰器的工作原理、垃圾回收机制、进程与线程的区别及全局解释器锁(GIL)的影响等,并提供了详细的解释与示例代码。
15 0
|
11天前
|
安全 Java 调度
python3多线程实战(python3经典编程案例)
该文章提供了Python3中多线程的应用实例,展示了如何利用Python的threading模块来创建和管理线程,以实现并发执行任务。
12 0
|
15天前
|
并行计算 API 调度
探索Python中的并发编程:线程与进程的对比分析
【9月更文挑战第21天】本文深入探讨了Python中并发编程的核心概念,通过直观的代码示例和清晰的逻辑推理,引导读者理解线程与进程在解决并发问题时的不同应用场景。我们将从基础理论出发,逐步过渡到实际案例分析,旨在揭示Python并发模型的内在机制,并比较它们在执行效率、资源占用和适用场景方面的差异。文章不仅适合初学者构建并发编程的基础认识,同时也为有经验的开发者提供深度思考的视角。
下一篇
无影云桌面