zoukankan      html  css  js  c++  java
  • python线程+队列(queue)

    ---恢复内容开始---

    python的线程学习

    用处 
    pocpiliang脚本的编写
    

    函数式:调用 _thread 模块中的start_new_thread()函数来产生新线程。语法如下:

    _thread.start_new_thread ( function, args[, kwargs] )

    参数说明:

    • function - 线程函数。
    • args - 传递给线程函数的参数,他必须是个tuple类型。
    • kwargs - 可选参数。
    import _thread
    import time
    为线程定义一个函数
    def print_time(threadName,delay):
        i=0
        while i<5:
            time.sleep(delay)
            i=i+1
            print("%s,%s"%(threadName,time.ctime(time.time())))
    try:
    _thread.start_new_thread(print_time,("first",2,))
    _thread.start_new_thread(print_time,("second",4,))
    except:
        print("太快了")

    我们可以看见 这个线i<5发送四次包 first发两次  second发一次

    线程模块
    
    Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。
    
    _thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。
    
    threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:
    
        threading.currentThread(): 返回当前的线程变量。
        threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
        threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
    
    除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
    
        run(): 用以表示线程活动的方法。
        start():启动线程活动。
    
        join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
        isAlive(): 返回线程是否活动的。
        getName(): 返回线程名。
        setName(): 设置线程名。
    import threading
    import time
    class myThread(threading.Thread):
        def __init__(self,threadID,name,counter):
            threading.Thread.__init__(self)
            self.threadID = threadID
            self.name =name
            self.counter =counter
        def run(self):
            print("开始线程"+self.name)
            print_time(self.name,self.counter,5)
            print("退出线程"+self.name)
    def print_time(threadName,delay,counter):
        while counter>0:
            time.sleep(delay)
            print("%s: %s" % (threadName, time.ctime(time.time())))
            counter=counter-1
    
    #创建新线程
    thread1 =myThread(1,"第一个线程",1)
    thread2 =myThread(2,"第二个线程",2)
    
    # 开启新线程
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    print ("退出主线程")

    可以看见这里我们调用线程

     

     那么接下来重点来了

    多线程

    多线程的优势在于可以同时运行多个任务(至少感觉起来是这样)。但是当线程需要共享数据时,可能存在数据不同步的问题。

    考虑这样一种情况:一个列表里所有元素都是0,线程"set"从后向前把所有元素改成1,而线程"print"负责从前往后读取列表并打印。

    那么,可能线程"set"开始改的时候,线程"print"便来打印列表了,输出就成了一半0一半1,这就是数据的不同步。为了避免这种情况,引入了锁的概念。

    import threading
    import time
    
    class myThread (threading.Thread):
        def __init__(self, threadID, name, counter):
            threading.Thread.__init__(self)
            self.threadID = threadID
            self.name = name
            self.counter = counter
        def run(self):
            print ("开启线程: " + self.name)
            # 获取锁,用于线程同步
            threadLock.acquire()
            print_time(self.name, self.counter, 3)
            # 释放锁,开启下一个线程
            threadLock.release()
    
    def print_time(threadName, delay, counter):
        while counter:
            time.sleep(delay)
            print ("%s: %s" % (threadName, time.ctime(time.time())))
            counter -= 1
    
    threadLock = threading.Lock()
    threads = []
    
    # 创建新线程
    thread1 = myThread(1, "Thread-1", 1)
    thread2 = myThread(2, "Thread-2", 2)
    
    # 开启新线程
    thread1.start()
    thread2.start()
    
    # 添加线程到线程列表
    threads.append(thread1)
    threads.append(thread2)
    
    # 等待所有线程完成
    for t in threads:
        t.join()
    print ("退出主线程")

     可以看见是先开始线程1然后线程一完了在开线程二

    线程优先级队列( Queue)

    线程优先级队列( Queue)
    
    Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列 PriorityQueue。
    
    这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。
    
    Queue 模块中的常用方法:
    
        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() 实际上意味着等到队列为空,再执行别的操作
    

     队列1 单向先进先出队列

    import queue
    #单向队列
    q = queue.Queue(5)
    print(q.maxsize)
    for i in range(4):
        q.put(i)
    print(q.get())
    print(q.qsize())
    #先进后出队列

     此时q.get()从队列里面取出来的是0 q.qsize还剩3个所以输出3

    如果代码改成

    import queue
    #单向队列
    q = queue.Queue(5)
    print(q.maxsize)
    for i in range(4):
        q.put(i)
        print(q.get())
    print(q.qsize())
    #先进后出队列
    

     那么将输出  进一个出一个 那么队列为空 q.qsize为0

     接下来是先进后出队列

    import queue
    q =queue.LifoQueue()
    for i in range(5):
        q.put(i)
    print(q.get())
    print(q.qsize())

    那么看看运行效果

     和我们预想的一样

    接下来是优先级队列的讲解

    import queue
    q =queue.PriorityQueue()
    q.put((5, 5454))
    q.put((5, 532566))
    q.put((3, 555))
    q.put((7, 344))
    print(q.get())
    print(q.get())

    优先级队列put进去的是一个元祖,(优先级,数据),优先级数字越小,优先级越高 话不多说我们看代码

    如果有两个元素优先级是一样的,那么在出队的时候是按照先进先出的顺序的。

     接下来是双端队列的讲解 看代码

    import queue
    q =queue.deque()
    for i in range(3):
        q.append(i) 尾部加入
    for c in range(5,8):
        q.appendleft(c) 首部加入
    q.insert(2,"我是二号位") 任意位置插入
    for i in range(10):
        print(q.pop()) 从尾部出
    

  • 相关阅读:
    ZOJ 2158 Truck History
    Knight Moves (zoj 1091 poj2243)BFS
    poj 1270 Following Orders
    poj 2935 Basic Wall Maze (BFS)
    Holedox Moving (zoj 1361 poj 1324)bfs
    ZOJ 1083 Frame Stacking
    zoj 2193 Window Pains
    hdu1412{A} + {B}
    hdu2031进制转换
    openjudge最长单词
  • 原文地址:https://www.cnblogs.com/-zhong/p/11708546.html
Copyright © 2011-2022 走看看