python之多线程

来源:互联网 发布:js 获取div自定义属性 编辑:程序博客网 时间:2024/06/08 01:18

threading模块与lock

<span style="font-family:Microsoft YaHei;font-size:12px;"><span style="font-family:Microsoft YaHei;"># -*- coding: utf-8 -*-import threading   class myThread(threading.Thread):      def __init__(self, name):          threading.Thread.__init__(self)          self.t_name = name                def run(self):          global num          while True:              mylock.acquire()              print '\nThread(%s) locked, Number: %d'%(self.t_name, num)              if num>=4:                  mylock.release()                  print '\nThread(%s) released, Number: %d'%(self.t_name, num)                  break              num+=1              print '\nThread(%s) released, Number: %d'%(self.t_name, num)              mylock.release()                  if __name__== '__main__':     mylock = threading.RLock()      num=0      thread1 = myThread('A')      thread2 = myThread('B')      thread1.start()      thread2.start()    thread1.join()    thread2.join()      print 'finished'</span></span>

1,在自己的线程类的__init__里调用threading.Thread.__init__(self, name = threadname)
Threadname为线程的名字
2,run(),通常需要重写,编写代码实现做需要的功能。
3,getName(),获得线程对象名称
4,setName(),设置线程对象名称
5,start(),启动线程
6,jion([timeout]),等待另一线程结束后再运行。
7,setDaemon(bool),设置子线程是否随主线程一起结束,必须在start()之前调用。默认为False。
8,isDaemon(),判断线程是否随主线程一起结束。
9,isAlive(),检查线程是否在运行中。


Queue

<span style="font-family:Microsoft YaHei;font-size:12px;"><span style="font-family:Microsoft YaHei;">import Queue  import random, threading, timeclass Producer(threading.Thread):      def __init__(self, t_name, queue):          threading.Thread.__init__(self, name=t_name)            self.data=queue     def run(self):            for i in range(5):                print "%s: %s is producing %d to the queue!\n" %(time.ctime(), self.getName(), i)               self.data.put(i)            #调用队列对象的put()方法在队尾插入一个项目。              #put()有两个参数,第一个item为必需的,为插入项目的值;            #第二个block为可选参数,默认为True。            #如果队列当前为空且block为True,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为False,put方法将引发Full异常。            time.sleep(2)          print "%s: %s finished!" %(time.ctime(), self.getName())    class Consumer(threading.Thread):       def __init__(self, t_name, queue):          threading.Thread.__init__(self, name=t_name)          self.data=queue      def run(self):          for i in range(5):              val = self.data.get()             #调用队列对象的get()方法从队头删除并返回该项目。            #可选参数为block,默认为True。            #如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。            #如果队列为空且block为False,队列将引发Empty异常。             print "%s: %s is consuming. %d in the queue is consumed!\n" %(time.ctime(), self.getName(), val)              time.sleep(1)          print "%s: %s finished!" %(time.ctime(), self.getName())  #理论上consumer消费比较快,但当queue为empty时,queue会使线程暂停  if __name__ == '__main__':      queue = Queue.Queue(10)  #可通过可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。                       producer = Producer('Pro.', queue)        consumer = Consumer('Con.', queue)       producer.start()      consumer.start()      producer.join()       consumer.join()      print 'All threads terminate!' </span></span>

python queue模块有三种队列:

1、python queue模块的FIFO队列先进先出。
2、LIFO类似于堆。即先进后出。
3、还有一种是优先级队列级别越低越先出来。 

针对这三种队列分别有三个构造函数:
1、class Queue.Queue(maxsize) FIFO 
2、class Queue.LifoQueue(maxsize) LIFO 
3、class Queue.PriorityQueue(maxsize) 优先级队列 

介绍一下此包中的常用方法:

Queue.qsize() 返回队列的大小 
Queue.empty() 如果队列为空,返回True,反之False 
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应 
Queue.get([block[, timeout]])获取队列,timeout等待时间 
Queue.get_nowait() 相当Queue.get(False)
非阻塞 Queue.put(item) 写入队列,timeout等待时间 
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作



threading.local

在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁。
一旦在主线程实例化了一个local,它会一直活在主线程中,
并且又主线程启动的子线程调用这个local实例时,它的值将会保存在相应的子线程的字典中。
ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,
这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。

class _DbCtx(threading.local):
由于_db_ctxthreadlocal对象,所以,它持有的数据库连接对于每个线程看到的都是不一样的。任何一个线程都无法访问到其他线程持有的数据库连接。

0 0
原创粉丝点击