Python基础-Threading

来源:互联网 发布:nginx官网 编辑:程序博客网 时间:2024/06/03 18:53

基本操作

  • 导入模块

    import threading
  • 获取已激活的线程数

    hreading.active_count()
  • 查看所有线程信息

    threading.enumerate()#[<_MainThread(MainThread, started 140580259493696)>]
  • 查看现在正在运行的线程

    threading.current_thread()
  • 添加线程,threading.Thread()接收参数target代表这个线程要完成的任务,需自行定义

    def thread_job():    print('This is a thread of %s' % threading.current_thread())def main():    thread = threading.Thread(target=thread_job,)   # 定义线程     thread.start()  # 让线程开始工作if __name__ == '__main__':    main()输出:This is a thread of <Thread(Thread-1, started 140662715672320)>

join 功能

要遵循顺序,可以在启动线程后对它调用join。使用join对控制多个线程的执行顺序非常关键。

例子
#-*- coding:utf-8 -*-import threadingimport timedef T1_job():    print("T1 start\n")    for i in range(10):        time.sleep(0.1)    print("T1 finish\n")def T2_job():    print("T2 start\n")    print("T2 finish\n")thread_1 = threading.Thread(target=T1_job, name='T1')thread_2 = threading.Thread(target=T2_job, name='T2')thread_1.start() # 开启T1thread_1.join()thread_2.start() # 开启T2thread_2.join()print("all done\n")

输出

T1 start
T1 finish
T2 start
T2 finish
all done

Queue

queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递

创建一个 Queue 对象

import Queue
q = Queue.Queue(maxsize = 10)

通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。

将一个值放入队列中

q.get()

q = Queue.Queue() 常用方法

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

例子

实现一个线程不断生成一个随机数到一个队列中(考虑使用Queue这个模块),一个线程从上面的队列里面不断的取出奇数。
import random,threading,time
from Queue import Queue

#生产者线程class Producer(threading.Thread):    def __init__(self, t_name, queue):        threading.Thread.__init__(self,name=t_name)        self.data=queue    def run(self):        results = []        for i in range(10):    #随机产生10个数字 ,可以修改为任意大小            randomnum=random.randint(1,99)            self.data.put(randomnum)  #将数据依次存入队列            results.append(randomnum)            time.sleep(0.1)        print "随机数"        print results        print " %s 完成!" %(self.getName())#消费者线程class Consumer_even(threading.Thread):    def __init__(self,t_name,queue):        threading.Thread.__init__(self,name=t_name)        self.data=queue    def run(self):        while 1:            try:                val_even = self.data.get(1,5)  #get(self, block=True, timeout=None) ,1就是阻塞等待,5是超时5秒                if val_even%2==0:                    time.sleep(1)                else:                    self.data.put(val_even)                    print val_even                    time.sleep(1)            except:     #等待输入,超过5秒  就报异常                print self.data.empty()                print self.data.qsize()                l = self.data.qsize()                for i in range (l):                    print self.data.get(i)                print "%s: %s 完成" %(time.ctime(),self.getName())                breakdef main():    queue = Queue()    producer = Producer('随机数线程', queue)    consumer_even = Consumer_even('获取基数线程', queue)    producer.start()    consumer_even.start()    producer.join()    consumer_even.join()    print '线程运行完成'if __name__ == '__main__':    main()

GIL 不一定有效率

Global Interpreter Lock全局解释器锁,python的执行由python虚拟机(也成解释器主循环)控制,GIL的控制对python虚拟机的访问,保证在任意时刻,只有一个线程在解释器中运行。所以GIL 不一定有效率。

线程锁 Lock

线程1得到了结果,想要让线程2继续使用1的结果进行处理,则需要对1lock,等到1执行完,再开始执行线程2。一般来说对share memory即对共享内存进行加工处理时会用到lock。

例子

import threadingdef job1():    global A, lock    lock.acquire()    for i in range(10):        A += 1        print 'job1', A    lock.release()def job2():    global A, lock    lock.acquire()    for i in range(10):        A += 10        print 'job2', A    lock.release()if __name__ == '__main__':    lock = threading.Lock()    A = 0    t1 = threading.Thread(target=job1)    t2 = threading.Thread(target=job2)    t1.start()    t2.start()    t1.join()    t2.join()
原创粉丝点击