美文网首页python学习实践
python多线程一——基础

python多线程一——基础

作者: 小奚有话说 | 来源:发表于2017-09-08 12:56 被阅读39次
    进程和线程

    进程(Process)是计算机中的程序关于数据集合上的一次活动,是系统进行资源分配和调度的基本单位。简单的说,进程是正在运行的程序的实例。
    一般来说,进程一般由文本区域、数据区域和堆栈组成。文本区域存储处理器执行的代码,数据区域存储变量和进程执行期间使用的动态分配的内存,堆栈则存储活动过程中调用的指令和本地变量。

    线程(Thread)是程序执行流的最小单元,线程只拥有运行所必须的资源,其他的资源和该进程中的其他线程共享。有时也被称之为轻量级进程(LightWeight Process,LWP)。一般一个进程中都有一个主线程。

    各自优缺点:
    进程拥有独立的地址空间和资源,进程间通信IPC比较麻烦,当一个进程崩溃后,不会对其他进程造成影响,故多进程程序比较健壮。但进程间切换耗费的资源比较大,时间较长。
    线程由于共享所属进程的资源,故线程间通信比较简单。线程所拥有的资源比较少,线程间的切换耗时短。

    PIL

    说起python和线程,那就不得不说一下PIL了,PIL是全局解释器锁(Global Interpreter Lock),该锁保证同时只能有一个线程运行。
    在多线程中,python虚拟机的运行方式如下:

    1. 设置GIL
    2. 切换进一个线程运行
    3. 执行一下一个操作:
     - 指定数量的字节码指令
     - 线程主动让出控制权
    4. 切换线程
    5. 解锁GIL
    

    对于python来说,GIL会在线程进行I/O调用前被释放,以便其他的线程运行,这也就是Python更适合做I/O密集型的工作。

    python中提供了多个模块来支持多线程编程,如thread,threading,Queue模块,其中thread模块提供了基本的线程和锁定支持,threading提供了更高级别、功能更全面的线程管理,Queue模块可以创建队列数据结构,在多个线程之间进行数据共享。

    thread模块
    函数方法 描述
    thread模块函数
    start_new_thread(function,args,kwargs=None) 派生一个新的线程
    allocate_lock() 分配LockType锁对象
    exit() 退出线程
    LockType锁对象方法
    acquire(wait=None) 获取锁对象
    locked() 是否获取锁对象
    release() 释放锁对象

    一般来说thread不常用,原因如下:

    1. thread模块中所拥有的同步元语只有一个,即LockType,
    2. thread对于进程的进入退出没有控制,当主线程结束时,所有的其他线程也会强制结束,不会发出警告或清理。
    3. 不支持守护线程
    4. thread所支持的操作很少

    在python3中thread模块被更名为_thread
    下面给出一个python3关于_thread的简单例子:

    import _thread
    import random
    from time import ctime, sleep
    
    def loop(nloop, nsec, lock):
        print('start loop:', nloop, 'nsec:', nsec, 'at:', ctime())
        sleep(nsec)
        print('end loop', nloop, 'done at:', ctime())
        lock.release()
    
    def main():
        print('starting at:', ctime())
        locks = []
        for i in range(2):
            lock = _thread.allocate_lock()
            lock.acquire()
            locks.append(lock)
    
        for i in range(2):
            _thread.start_new_thread(loop, (i, random.randint(1, 4), locks[i]))
    
        for i in range(2):
            while locks[i].locked():
                pass
    
        print('all down at:', ctime())
    
    if __name__ == '__main__':
        main()
    

    在这个例子中,首先通过_thread_allocate_lock()来生成锁对象,并通过acquire()来获取锁,这样就相当于将锁锁上,然后将该锁传递给每个线程中。
    线程中操作很简单,休眠传递过来的时间,然后释放锁。
    在主线程中,不停的去判断两个锁是否锁住,避免主线程执行完导致两个线程直接被强制结束。运行的结果如下:

    starting at: Thu Sep  7 09:57:36 2017
    start loop: 0 nsec: 2 at: Thu Sep  7 09:57:36 2017
    start loop: 1 nsec: 4 at: Thu Sep  7 09:57:36 2017
    end loop 0 done at: Thu Sep  7 09:57:38 2017
    end loop 1 done at: Thu Sep  7 09:57:40 2017
    all down at: Thu Sep  7 09:57:40 2017
    

    python多线程就暂时讲到这里了。

    相关文章

      网友评论

        本文标题:python多线程一——基础

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