Python线程

time.sleep与全局解释器锁

Cpython解释器中有全局解释器锁(GIL),一次只允许使用一个线程执行Python字节码,因此一个python进程通常不能同时使用多个CPU核心。

然而标准库中,所有C语言编写I/O操作的函数,等待操作系统返回结果时,都会释放GIL。

比如像time.sleep()函数:作用是在一段时间不会返回或者执行其他代码。

一段时间结束后,time.sleep也会释放GIL,从而允许其他线程进行。

使用Python处理CPU密集型工作时,应该试试PyPy,futures模块。

或者使用分布式计算引擎Apache Spark,支持把Python对象当做数据。

多线程

import time,datetime
startTime=datetime.datetime(2029,10,31,0,0,0)
while datetime.datetime.now() < startTime:
    time.sleep(1)

print('Happy Halloween 2029')

这段代码指定2029年10月31日作为开始时间,不断地调用time,sleep(1),在2029年10月31日没到那天,程序将一直“沉睡”。

这是因为前面提到的全局解释器锁的原因。Python程序在默认的情况下,只有一个执行线程。

单线程程序的执行就像一个”逐行”读书的手指,而多线程程序的执行可以为有多个“逐行”读书的手指。

为了不必让所有代码等待,我们可以在原来的线程外,在创建一个线程,这个单独的线程可以执行延迟或安排的代码。

为此我们可以这样做:

import threading,time
print('程序启动.')
def takeANap():
    time.sleep(5)
    print('Wake up!')
threadObj=threading.Thread(target=takeANap)
threadObj.start()
print('程序结束.')

 输出结果会是这样


程序启动.

程序结束.

Wake up!


 为什么最后两个顺序是这样的呢?

这是因为当程序运行到start()函数时,takeANap函数已经被放入一个新的执行线程中。这个时候相当于

一个手指即将执行:print('程序结束.'),另一个手指已经在takeANap函数入口处,这个时候主线程会打印出程序结束内容,新线程会在小睡后打印Wake up!

通常程序会在最后一行代码执行后终止,对于此例则有两个线程。在程序的所有执行线程终止前,程序不会终止。所以即使主线程已经完成使命,新线程仍会sleep。

多线程会遇到的问题:并发问题

如果这些线程同时读写变量,会导致互相干扰,最终会发生并发问题。

有关线程的初学者教程更多见:

http://nostarch.com/automatestuff/

原文地址:https://www.cnblogs.com/liuguangshou123/p/13582748.html