(python)threading多线程

一、前言

我们在对大量数据做类似操作的时候,如果仅仅使用一种串行逻辑,无疑让后面的许多同类操作持久等待,耗费许多时间。实际上,我们可以选择许多种并行的模块来实现类似操作同时执行,比如同时爬取多个网站,同时对多个文本进行类似处理等。这里介绍笔者学习threading的经历和步骤。

生产者消费者模型代码是跟优秀博文学习的,原文请点击原文链接。这里以此为例子,加入了笔者的理解说明和改动后代码,较大篇幅为原创内容,因此注为原创。

二、常用模块及解释

1、threading

即多线程模块。

2、time

主要使用time.sleep()函数来实现短暂的等待。
偶尔也会用运行前t_start=time.time()
运行后print(time.time()-t_start)
来标记运行的时间。

3、queue

即队列,规定了传入数据方和运行函数之间“管道”的大小,
当管道中无数据,则运行方等待;
当管道中数据已满,则传入数据方等待。

三、运行代码及解释


import time, threading, queue

q = queue.Queue(maxsize=10)  # 声明队列


def Producer(name):
    '''生产者'''
    count = 1
    while True:
        q.put(count)  # 往队列中添加数据
        q.put(count)  # 往队列中添加数据
        q.put(count)  # 往队列中添加数据
        q.put(count)  # 往队列中添加数据
        q.put(count)  # 往队列中添加数据
        print("生产后——len(queue):",q.qsize()) #查看队列长度
        print("[%s] 生产了第%s个包子\n" % (name, count))
        count += 1
        time.sleep(2)


def Consumer(name):
    '''消费者'''
    while True:
        i = q.get()  # 从队列中取数据
        print("取出后——len(queue):",q.qsize()) #查看队列长度
        print("[%s] 吃了第%s个包子\n" % (name, i))
        time.sleep(2)


'''设置多线程'''
p = threading.Thread(target=Producer, args=("店长",))
c1 = threading.Thread(target=Consumer, args=("小明",))
c2 = threading.Thread(target=Consumer, args=("小亮",))
c3 = threading.Thread(target=Consumer, args=("小红",))

'''线程开启'''
p.start()
c1.start()
c2.start()
c3.start()

由于它们之间是同时执行的,所以输出比较混乱,不过我们仍然可以看出一些问题。比如说
1、队列长度从未超过我们预定的长度。
2、由于生产较快,因此常常需要等待,而此时三个消费者消耗的速度没有受到影响,因此虽然我们标记的暂停时间都是两秒钟,它们实际运行的时间是消费者速度更快。

我们不难得出第一条结论,我们应当设置传入数据方和运行函数之间相对匹配的速度。否则会面对数据积压乃至丢失的风险、或者是运行速度受到生产者速度限制的情况。
另外,这里是一条一条的添加,因此数据一直可以添加进去。在实际操作中,可能发生死锁的情况,即“生产者一次生产的数量过大而无法进入管道,消费者一次消耗的数据较大而传入数据不足”导致的互相无限等待的情况,此时应当设置较大的队列规格

笔者目前关于threading的使用还不够熟悉和完善,例如join、wait等函数还没有涉及,随着后续的学习和使用会逐渐完善。

猜你喜欢

转载自blog.csdn.net/qq_41584385/article/details/100169878
今日推荐