美文网首页
Python之多线程

Python之多线程

作者: yang2yang | 来源:发表于2016-09-05 00:49 被阅读138次

什么是线程?

要弄清楚线程的定义,往往就要和进程相互比较,从比较中才能更准确地明白一个东西的定义。首先有个数量关系是这样的,进程是由多线程组成的,每个进程起码都有一个线程
然后重点是有人说:

进程和线程简单而基本靠谱的定义如下:
1. 进程:程序的一次执行
2. 线程:CPU的基本调度单位

给一句话的定义,其实没有什么意思。但是,做为最根本的落脚点,放着也是极好的。
阮大神的这篇blog写的很通俗,但是不清楚,不深入,但是文章加评论却是相当有意思。

在我眼中的定义的理解

  • 进程:程序的一次执行?
    所谓程序的一次执行,就是指有自己的内存空间。就程序代码而言,就是当有全局变量,局部变量的时候,两者是不会互相影响的,每个进程都有自己独立的内存空间。其实,这些都是操作系统在影响着,你看,每个进程都有自己的内存空间,那么每个进程自己使用自己的东西的时候,就不会拿错东西,这样一来,我的程序员师叔们编程序的时候就不会弄错了,不用考虑这个变量是属于哪个进程这种问题了。(也不知道当时他们是不是这么想的:( )(那么问题来了,操作系统层是这样的,那么硬件层呢?CPU层到底是怎么实现的呢?)
  • 线程:CPU的基本调度单位?
    这个问题还没有考虑清楚,下次看看书,再来补充。有一个肤浅的一点就是在实际编程的过程中,全局变量是可以被所有线程所访问到的。(太肤浅了。。)

Python的多线程实现(Python3实现)

Python的标准库提供了两个模块:_threadthreading_thread是低级模块,threading是高级模块,对_thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。
下面是廖大官网的例子,感觉非常不错,搬过来了哈。

import time, threading

# 假定这是你的银行存款:
balance = 0

def change_it(n):
    # 先存后取,结果应该为0:
    global balance
    balance = balance + n
    balance = balance - n

def run_thread(n):
    for i in range(100000):
        change_it(n)

t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)

如果是初次在学校中开始接触到线程的话,其实有一点是十分困惑的。(反正我是非常困惑的)就是有一种欲望是想看看threading这个模块的Thread函数的实现是什么?或者说就想弄清楚,弄明白run_thread,这个函数命传递进去了之后,程序代码到底做了什么?为什么要t1.start()t1.join()?就很奇怪,一个好好的函数,为什么要target传一个函数名,args参数传函数的参数,一起传不好吗?

然后当你真的点击去看实现的时候,就会一脸懵逼。那么如果控制这种想法呢?反正我就明白一点就是,学习的过程,并不是你前面的都明白的,下一个点也能明白的,有时候明白这种明白,知道这个点不是现阶段的问题这个事实是非常好的。

API中的几个注意点:

  1. target传递的是一个函数名,而不是函数调用,如果你看过Python的线程的API的话,也是要注意这一点的。
  2. balance这种全局变量是可以被所有线程访问到的。然后就有了锁的概念,那不是另一个世界了。
  3. 线程的start()join()函数的作用,线程的调度是由操作系统决定的,没有先后顺序,高级语言的有些一条语句其实可以拆分之类的概念,这里是不会提的,不然显得没重点,可以看一下廖大的教程,很详细。
  4. 下面是其中一种运行结果。
初始值 balance = 0

t1: x1 = balance + 5  # x1 = 0 + 5 = 5

t2: x2 = balance + 8  # x2 = 0 + 8 = 8
t2: balance = x2      # balance = 8

t1: balance = x1      # balance = 5
t1: x1 = balance - 5  # x1 = 5 - 5 = 0
t1: balance = x1      # balance = 0

t2: x2 = balance - 8  # x2 = 0 - 8 = -8
t2: balance = x2   # balance = -8

结果 balance = -8
  • 线程中锁。
balance = 0
lock = threading.Lock()

def run_thread(n):
    for i in range(100000):
        # 先要获取锁:
        lock.acquire()
        try:
            # 放心地改吧:
            change_it(n)
        finally:
            # 改完了一定要释放锁:
            lock.release()

还真是,这个API比JAVA中的要简单很多。

  • 还有一种是一个python的类继承的thread的API还没有写,下次补充。显示这个继承的API不好,类中参杂了很多不是这个类的东西。

GIL

GIL是全局解释器锁,可以看这个东西的英文比较能懂。因为这个东西的存在,Python的多线程,不论怎么样都只能充分使用CPU的一个核心。有下面几点要注意:

  1. Python是一种语言,语言也可以理解为一种语法标准,在这个标准里面是没有GIL的,但是这个语言的实现,官方的解释去CPython中是用了GIL来实现的,但是比如JPython是没有这个概念的。(那么问题来了,为什么还是有那么多人使用CPython?)
  2. Python3中的GIL也是一样存在的,只是Python3中对GIL的一个多线程比单线程还要慢的这一个问题进行了修复,没有从根本上解决这个问题。
  3. 想充分利用多核CPU的话,可以使用多进程。(那么为什么多进程可以避开GIL而充分使用CPU呢?)

最后之前

为什么多线程或者说多进程会比单进程快呢?对于IO密集型,计算密集型?可以从CPU和操作系统的角度来谈谈这个问题吗?计算机有几个IO方式呢,比如DMA是什么,有什么不同?计算机IO的时候,是需要CPU的运行吗?需要吗?不需要吗?不需要的话,又是谁把磁盘中的数据读到内存中的呢?除了CPU还有谁有这个能力呢?线程和进程在CPU这个层面到底是什么瓜葛呢?待我好好看书,来回答这个问题。

最后

写给未来的自己,也写给读到最后的你,能力有限,如有错误,请交流谈论及指正,如果有帮助,请评论或者点击喜欢,谢谢。

参考:

进程与线程的一个简单解释
廖雪峰的官方教程之多线程
Python 之父谈 Python
Python 3.2与更好的GIL

相关文章

  • Python多线程

    目录:一、线程的创建二、多线程互斥锁三、线程间通信四、线程池 Python并发之多线程 一、线程的创建 单线程示例...

  • python之多线程

    注:本文是廖大的教程文章,本人也在学习,因为老是记不住,自己手打一边,代码也是亲自测试。廖大传送门 多进程 多个任...

  • Python之多线程

    什么是线程? 要弄清楚线程的定义,往往就要和进程相互比较,从比较中才能更准确地明白一个东西的定义。首先有个数量关系...

  • python之多线程

    进程的概念:以一个整体的形式暴露给操作系统管理,里面包含各种资源的调用。 对各种资源管理的集合就可以称为进程。线程...

  • python之多线程

    1. 相关概念 1.1 解释器 Python 解释器的主要作用是将我们在 .py 文件中写好的代码交给机器去执行,...

  • python之多线程与多进程入门

    python之多线程与多进程 关键词: GIL锁,IO繁忙,线程安全,线程同步,进程池,进程通信,队列 GIL锁;...

  • python多线程

    python基础之多线程锁机制 GIL(全局解释器锁) GIL并不是Python的特性,它是在实现Python解析...

  • iOS开发之多线程(5)—— Pthreads

    文集 iOS开发之多线程(1)—— 概述iOS开发之多线程(2)—— ThreadiOS开发之多线程(3)—— G...

  • iOS开发之多线程(4)—— Operation

    文集 iOS开发之多线程(1)—— 概述iOS开发之多线程(2)—— ThreadiOS开发之多线程(3)—— G...

  • iOS开发之多线程(6)—— 线程安全与各种锁

    文集 iOS开发之多线程(1)—— 概述iOS开发之多线程(2)—— ThreadiOS开发之多线程(3)—— G...

网友评论

      本文标题:Python之多线程

      本文链接:https://www.haomeiwen.com/subject/spelettx.html