关于Python的进程线程协程之thread模块
2017-04-25 18:13
796 查看
简介
thread模块为python下的多线程处理,提供了产生线程的基本方法和锁方法的,支持建议不要和threading模块同时使用。关于线程锁
所谓的锁,即基本的同步数据锁对象lock object,也称原语锁,简单锁,互斥锁,二值信号量,作用是同步数据,防止产生脏数据thread模块方法和锁对象的描述
start_new_thread(function,args,kwargs=None) 产生一个新线程对象,在新线程中调用指定参数(args和可选的kwargs)的函数functionallocte_lock() 分配一个LockType类型的锁对象
exit() 让线程退出
LockType类型锁对象方法
acquire(wait=None) 尝试获取锁对象
locked() 线程对象如果获取了锁对象返回True,否则返回False
release() 释放锁
实例一:
未使用thread模块的实例解释器将变量以及函数读入内存之后,执行main函数,方法依次调用,顺序执行
from time import sleep,ctime """ the process that no mode of thread """ def loop0(): '''function for sleep 4s ''' print "start loop0 at: ",ctime() sleep(4) print "end loop0 at: ",ctime() def loop1(): '''function for sleep 2s ''' print "start loop1 at: ", ctime() sleep(2) print "end loop1 at: ", ctime() def main(): '''function of main''' print "process start at: ".upper(),ctime() loop0() loop1() print "process end at: ".upper(),ctime() if __name__ == '__main__': main()
执行结果如下:
PROCESS START AT: Tue Apr 25 16:48:04 2017 start loop0 at: Tue Apr 25 16:48:04 2017 end loop0 at: Tue Apr 25 16:48:08 2017 start loop1 at: Tue Apr 25 16:48:08 2017 end loop1 at: Tue Apr 25 16:48:10 2017 PROCESS END AT: Tue Apr 25 16:48:10 2017
实例二:
使用thread模块的实例#_*_utf-8_*_ import thread from time import sleep,ctime """ the process that have mode of thread """ def loop0(): '''A function for sleep 4s ''' print "start loop0 at: ",ctime() sleep(4) print "end loop0 at: ",ctime() def loop1(): '''A function for sleep 2s ''' print "start loop1 at: ", ctime() sleep(2) print "end loop1 at: ", ctime() def main(): '''A function of main''' print "process start at: ".upper(),ctime() thread.start_new_thread(loop0,()) thread.start_new_thread(loop1,()) sleep(6) print "process end at: ".upper(),ctime() if __name__ == '__main__': main()
执行结果如下:
PROCESS START AT: Tue Apr 25 16:50:38 2017 start loop0 at: Tue Apr 25 16:50:38 2017 start loop1 at: Tue Apr 25 16:50:38 2017 end loop1 at: Tue Apr 25 16:50:40 2017 end loop0 at: Tue Apr 25 16:50:42 2017 PROCESS END AT: Tue Apr 25 16:50:44 2017
ps:如果在main函数里去掉sleep(6),那么,在主线程里将运行函数loop1和loop2的两个线程产生后,主线程将继续运行,不管产生的两个新线程是否执行完成,但此时系统一定会报错,如下:
PROCESS START AT: Tue Apr 25 16:56:36 2017 PROCESS END AT: Tue Apr 25 16:56:36 2017 Unhandled exception in thread started by sys.excepthook is missing lost sys.stderr Unhandled exception in thread started by sys.excepthook is missing lost sys.stderr
为了避免以上情况(即当主线程退出时,所有的子线程不论是否还在工作,都会被强行退出)的出现,由此引入了守护线程,比thread更高级的threading模块支持守护线程,不过我们可以用后文讲到的锁机制来模拟守护线程的作用作为弥补
线程锁:thread模块的锁方法
针对python的GIL,python的多线程处理在cpu性能欠佳的情况下往往会产生脏数据,比如多个线程在同时修改共享数据,例如全局变量,此时可能会产生数据不同步,因为python2.7内部默认每一个线程执行100条cpu指令(差不多这么多条),执行完了我切换到另一个线程执行100条指令,假设在某个场景下,主线程产生两个线程A,B,同时修改全局变量i=0,让它增一,A线程刚拿到i的初始值准备修改,而并未开始修改,此时cpu的100条指令执行完,此时保存现场,切换到B线程执行,它获取到i的初始值依旧未变,即跟A拿到的一样,那么,照这样执行下去,最后A,B修改后返回的i的值就会是相同的即i=1,此时,就产生了数据不同步,脏数据产生。这也是锁出现的原因。实例三:
thread模块:未设置锁的多线程实例#_*_utf-8_*_ import thread """ the process that have mode of thread and no Lock """ count = 0 def loop(arg): '''function for modify the global value count and sleep 2s ''' global count count += 1 sleep(1) print "count of modified in loop %s is :"%arg,count def main(): '''function of main''' print "begin count = ".upper,count for i in range(50): thread.start_new_thread(loop,(i,)) sleep(10) print "final count = ".upper,count if __name__ == '__main__': main()
运行结果如下:
<built-in method upper of str object at 0x00000000034DD870> 0 count of modified in loop 0 is : count of modified in loop 2 is :1 2count of modified in loop 1 is : count of modified in loop 3 is :3 4count of modified in loop 4 is : count of modified in loop 6 is :6count of modified in loop 5 is : 7count of modified in loop 8 is :7 8 count of modified in loop 7 is :count of modified in loop 9 is : <built-in method upper of str object at 0x00000000034EF300> 10 10 10 ······此处省略n行······ count of modified in loop 44 is :count of modified in loop 41 is :41 Process finished with exit code 0
ps:*脏数据的产生*:由于产生的线程未设置互斥锁,导致全局变量count最终修改结果产生误差,并且所有的线程在输出的时候都在抢占输出中断导致输出乱序
实例四:
thread模块:设置锁的多线程实例#_*_utf-8_*_ import thread """ the process that have mode of thread and Lock """ count = 0 #global value num = 50 #number of threads Lock_Pool = [] #object of locks def loop(arg,Lp): '''function for modify the global value count ''' global count count += 1 print "count of modified in loop %s is :"%arg,count Lp.release() def Thread_End(arg): for i in range(arg): while Lock_Pool[i].locked :pass def LockPool(): '''A function that produce intantiation of Lock ''' for i in range(num): lock = thread.allocate() lock.acquire() Lock_Pool.append(lock) def main(): '''A function of main: produce Lock pool start every thread wait every thread finish in main until the all end ''' LockPool() #produce Locks print "begin count = ".upper,count for i in range(num): thread.start_new_thread(loop,(i,Lock_Pool[i])) Thread_End(num) #wait all threads end print "final count = ".upper,count if __name__ == '__main__': main()
其中的Thread_End函数就是本文实例二提到的模拟守护线程的功能,通过判断每个线程的锁是否还在获取状态来阻塞主线程,用这样的低级的一个一个判断的方法来弥补thread模块不支持守护线程的缺陷
def Thread_End(arg): for i in range(arg): while Lock_Pool[i].locked :pass
关于线程同步:其中函数LockPool的定义是为了,实现线程们的同步执行,避免有的线程还在获取锁,有的线程已经运行结束了
def LockPool(): '''A function that produce intantiation of Lock ''' for i in range(num): lock = thread.allocate() lock.acquire() Lock_Pool.append(lock)
相关文章推荐
- 关于Python的进程线程协程之threading模块(一)Thread类
- 关于Python的进程线程协程之threading模块(五)Time对象
- 关于Python的进程线程协程之threading模块(四)Condition对象
- 关于Python的进程线程协程之threading模块(三)Event对象
- 关于Python的进程线程协程之threading模块(二)Lock,RLock对象以及Semaphore,BoundedSemaphore对象
- Python中理解进程(Process),线程(Thread)和协程(Coroutines)的感悟
- Python:线程、进程与协程(3)——Queue模块及源码分析
- 【脚本语言系列】关于Python进程线程管理系统模块,你需要知道的事
- python 之线程、进程、协程
- Python 中的进程、线程、协程、同步、异步、回调
- Python:线程、进程和协程
- 简述Python中的进程、线程、协程
- python 线程、进程和协程
- Python 中的进程、线程、协程、同步、异步、回调
- Python 中的进程、线程、协程、同步、异步、回调
- 突破python缺陷,实现几种自定义线程池 以及进程、线程、协程的介绍
- python进程、线程、协程
- Python 中的进程、线程、协程、同步、异步、回调
- Python之线程、进程和协程
- 白话Python 进程,线程,协程