python学习实践

python多线程一——基础

2017-09-08  本文已影响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多线程就暂时讲到这里了。

上一篇 下一篇

猜你喜欢

热点阅读