进程和线程
进程(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不常用,原因如下:
- thread模块中所拥有的同步元语只有一个,即LockType,
- thread对于进程的进入退出没有控制,当主线程结束时,所有的其他线程也会强制结束,不会发出警告或清理。
- 不支持守护线程
- 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多线程就暂时讲到这里了。
网友评论