<PY><core python programming笔记>C18 多线程编程

来源:互联网 发布:阿里云架设ftp 编辑:程序博客网 时间:2024/05/17 00:06


C18   多线程编程

18.1 动机
可能中间过程需要子任务,本质上是异步的,需要有多个并发事务(事实上单CPU只能串行,通过分时处理看起来并行),
各个事务的运行顺序是不确定的,随机的,不可预测的。
顺序执行的程序必须使用非阻塞的I/O,或者可以是带有计数器的阻塞I/O
多线程编程是可能使用同一数据,这样就需要由单一的功能来组织这个数据操作,防止冲突
UserRequestThread     负责读取客户的输入,可能是一个I/O信道。请求放入线程队列中。
RequestProcessor        负责从队列中获取并处理请求,由下面的线程提供输出
ReplyThread                  负责给用户取出输出

18.2线程和进程
线程的组织范围比进程小
进程是可以去分配资源的,线程在进程中共享数据资源

18.3Python、线程和全局解释器锁
18.3.1  GIL--全局解释器锁
控制线程的运行
编写扩展时可以主动解锁GIL
18.3.2  退出线程
thread.exit()
sys.exit()
18.3.4  没有线程的情况
比如时间的控制sleep(second)就不好控制
18.3.5 threading
Python提供thread、threading、Quene模块(不推荐使用thread模块,因为功能很有限且与threading冲突,
且不支持守护线程)

18.4  thread模块
模块函数
start_new_thread(function,args kwargs=None)     指定参数,新建线程
allocate_lock()                                                               分配一个LockType类型的锁对象
exit()                                                                                让线程退出
LockType类型锁对象方法
acquire(wait=None)                                                     尝试获取锁对象
locked()                                                                          如果获取了锁对象返回True,否则返回False
release()                                                                         释放锁

#thread1.pyimport threadfrom time import sleep,ctimedef loop0():    print 'start loop 0 at:',ctime()    sleep(4)    print 'loop 0 done at:',ctime()def loop1():    print 'start loop 1 at:',ctime()    sleep(2)    print 'loop 1 done at:',ctime()def main():    print 'starting at:',ctime()    thread.start_new_thread(loop0,())    thread.start_new_thread(loop1,())    sleep(6)        #挂着主线程    print 'all done at:',ctime()if __name__=='__main__':    main()#thread2.py#coding=UTF-8#锁比sleep更合理一些import threadfrom time import sleep,ctimeloops=[4,2]def loop(nloop,nsec,lock):    print 'start loop',nloop,'at:',ctime()    sleep(nsec)    print 'loop',nloop,'done at:',ctime()    lock.release()    print 'released'def main():    print 'starting at:',ctime()    locks=[]    nloops=range(len(loops))    for i in nloops:        lock=thread.allocate_lock()        lock.acquire()        locks.append(lock)    for i in nloops:        thread.start_new_thread(loop,(i,loops[i],locks[i]))    for i in nloops:        while locks[i].locked():            pass    print 'all done at:',ctime()if __name__=='__main__':    main()

18.5 threading 模块
模块对象
Thread             表示一个线程的执行的对象
Lock                 锁原语对象(更thread模块里的锁对象相同)
RLock               可重入锁对象。使单线程可以再次获得已经获得了的锁(递归锁定)
Condition        条件变量对象能让一个线程停下来,等待其他线程满足了某个条件。
Event                通用的条件变量。在某个事件发生后多个线程都被激活
Semaphore     为等待锁的线程提供一个类似“等候室”的结构
BoundedSemaphore     和上面类似,但不允许超过初始值
Timer                 与Thread相似,只是它要等待一段时间后才开始运行
函数
start()               开始线程的执行
run()                 定义线程的功能的函数,一般会被子类重写
join(timeout=None)   程序挂起,直到线程结束,设置timeout是最大阻塞时间
getName()        获得线程名称
isAlive()             线程是否运行中
isDaemon()       返回线程的daemon标志
setDaemon(daemonic)   设置daemon为daemonic
18.5.1 使用threading模块

#coding=UTF-8import threadingfrom time import sleep,ctimeloops=[4,2,3,6]def loop(nloop,nsec):    print 'start loop',nloop,'at:',ctime()    sleep(nsec)    print 'loop',nloop,'done at:',ctime()def main():    print 'starting at:',ctime()    threads=[]    nloops=range(len(loops))    for i in nloops:        t=threading.Thread(target=loop,args=[i,loops[i]])        threads.append(t)    for i in nloops:        threads[i].start()#用start启动    for i in nloops:      #等待所有        threads[i].join() #允许主线程等待线程的结束    print 'all done at:',ctime()if __name__=='__main__':    main()#使用类#coding=UTF-8import threadingfrom time import sleep,ctimeloops=[3,5,7,2,4,8]class ThreadFunc(object):    def __init__(self,func,args,name=''):        self.name=name        self.func=func        self.args=args    def __call__(self):        apply(self.func,self.args)def loop(nloop,nsec):    print 'start loop',nloop,'at:',ctime()    sleep(nsec)    print 'loop',nloop,'done at:',ctime()def main():    print 'starting at:',ctime()    threads=[]    nloops=range(len(loops))    for i in nloops:  #create all threads        t=threading.Thread(target=ThreadFunc(loop,(i,loops[i]),loop.__name__))        threads.append(t)    for i in nloops: #start all threads        threads[i].start()    for i in nloops:        threads[i].join()    print 'alll done at:',ctime()if __name__=='__main__':    main()


18.5.3 threading模块中的其他函数
activeCount()           当前活动的线程对象的数量
currentThread()       返回当前线程对象
enumerate()             返回当前活动线程的列表
settrace()                  为所有线程设置一跟踪函数
setprofile()               为所有线程设置一个profile函数

18.5.4  生产者--消费者问题和Quene模块
queue(size)                创建一个大小为size的Queue对象
qsize()                         返回队列大小
empty()                       队列为空则返回True,否则返回False
full()                             队列为满则返回True,否则返回False
put(item,block=0)   把item放到队列中,如果给出了block,函数会一直阻塞到队列中有空间为止
get(block=0)             从队列中取一个对象,如果给力block,函数会一直阻塞到队列中有对象为止

18.6相关模块
thread
threading
Quene
mutex
SocketSever


0 0