python 线程间通信

线程间通信主要用到了Event()方法,我对其感性认知类似于锁。当一个线程里event调用等待方法wait()时,该线程即被堵塞,需要另一个线程使用event的set()方法,线程阻塞消失。这里还涉及到队列queue的一些使用,在代码里进行解释。

import threading
import logging
from queue import Queue
import time


def get_logger():
    logger = logging.getLogger("threading_eg")
    logger.setLevel(logging.DEBUG)
    fh = logging.FileHandler("C:\\Users\Administrator\Desktop\\test\\threading3.log")
    fmt = '%(asctime)s - %(name)s - %(threadName)s - %(message)s'
    formatter = logging.Formatter(fmt)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger


def creator(data, q, logger):
    """
    生成用于消费的数据,等待消费者完成处理
    """
    logger.debug('Creating data and putting it on the queue')
    for item in data:
        evt = threading.Event()
        q.put((item, evt))
        logger.debug('Waiting for data to be doubled')
        evt.wait()


def my_consumer(q, logger):
    """
    消费部分数据,并做处理

    这里所做的只是将输入翻一倍

    """
    while True:
        data, evt = q.get()
        logger.debug('data found to be processed: {}'.format(data))
        processed = data * 2
        logger.debug(processed)
        time.sleep(5)
        evt.set()
        time.sleep(2)
        if q.empty():
            break


if __name__ == '__main__':
    logger = get_logger()
    q = Queue()
    data = [5, 10, 13, -1]
    thread_one = threading.Thread(target=creator, args=(data, q, logger))
    thread_two = threading.Thread(target=my_consumer, args=(q, logger))
    thread_one.start()
    thread_two.start()

第一个函数为日志记录函数,不在解释。

第二个函数为生产者函数,即通过传入的列表,将列表里的数据传入队列queue中。

第三个函数为消费者函数,即将列表里的数据取出并翻倍再输出。

主线程里构造了日志对象和队列,创建了一个列表和两个线程,并启动线程。

现在理一理程序的执行逻辑:

当两个子线程启动后,线程1调用生产者函数,遍历列表。当取出第一个数据‘5’时,同时创建了一个Event对象,将Event与第一个数据‘5’打包放进队列,然后event调用wait方法,此时线程1阻塞。

线程2处于不断运行中,只有当队列为空时才退出该线程。由于线程1在线程2前启动,所以此时队列已经有了一个数据。

线程2取出队列里的数据,翻倍,强制等待了5s,后调用event.set()方法,此时线程1不再阻塞,立刻又将数据塞入队列中,此刻强制等待2s,由于线程1在2s前又塞入了一个数据,所以此时队列不为空,继续执行。

直到线程1将所有数据遍历完,队列里没有数据后,线程2同时结束,整个程序结束。


这里的结束程序本应该使用队列的take_done方法和join方法,但是我研究了一会都发现无法结束程序,最后自行写了while判断队列是否为空来结束程序。

你可能感兴趣的:(python)