Python3简单实现多任务(线程/协程篇)

简介: 写在前面上一篇文章[Python3简单实现多任务(多进程篇)]已经介绍了python多进程实现多任务的简单实现方法;这次讲一讲python创建多任务另外两种常见的方式:协程和线程线程多任务实现1:直接使用Thread创建线程...

写在前面

  • 上一篇文章[Python3简单实现多任务(多进程篇)]已经介绍了python多进程实现多任务的简单实现方法;
  • 这次讲一讲python创建多任务另外两种常见的方式:
  • 协程和线程


线程多任务实现1:直接使用Thread创建线程

from threading import Thread
import threading
import os
import time
import random

def not_know(thread_num):
    
    print("第%d线程吟唱:不知天上宫阙"%(thread_num))
    time.sleep(random.random())
    print("第%d线程吟唱:今夕是何年"%(thread_num))
    time.sleep(random.random())
    print("第%d号线程:<吟唱古诗>任务结束..."%(thread_num))

def main():
    for i in range(1, 6):
        num = len(threading.enumerate())
        print("当前线程数为:%d"%num)
        t = Thread(target=not_know, args=(i,))
        t.start()
        time.sleep(0.8)

if __name__ == "__main__":
    print("--->主函数开始运行<---")
    main()
    print("--->主函数运行完毕<---")

线程多任务实现2:定义类继承threading.Thread,然后重写run方法(run方法相当于功能函数)

from threading import Thread
import threading
import os
import random
import time

class the_cosmetic(threading.Thread):
    def __init__(self, num):
        self.num = num
        # 一定要记得调用父类构造方法
        threading.Thread.__init__(self)

    def run(self):
        print("-->第%d线程开始执行<--"%self.num)
        time.sleep(random.random())
        print("%d最有效的化妆品是什么?"%self.num)
        time.sleep(random.random())
        print("%dPhotoshop是最好的化妆品!"%self.num)
        time.sleep(random.random())
        print("-->第%d线程执行完毕<--"%self.num)

def main():
    print("-------->开始创建线程<--------")

    for i in range(1, 6):
        t = the_cosmetic(i)
        t.start()

    print("-------->线程创建完毕<--------")

if __name__ == "__main__":
    main()

协程多任务实现1:gevent(使用简单,推荐!需要pip安装gevent)

sudo pip3 install gevent

import time
import random
import gevent
from gevent import monkey

monkey.patch_all()

def peach(name):
    for i in range(1, 6):
        start_time = time.time()
        time.sleep(random.random())
        end_time = time.time()
        # 使用 round() 控制小数点位数!
        print("%s产出第%s个桃子,耗时%s"%(name, i, round(end_time - start_time, 2)))

def apple(name):
    for i in range(1, 8):
        start_time = time.time()
        time.sleep(random.random())
        end_time = time.time()
        print("%s产出第%s个苹果,耗时%s"%(name, i, round(end_time - start_time, 2)))

def main():
    # 注意:下面的语句,没有等号! 没有等号! 没有等号!
    gevent.joinall([
        gevent.spawn(peach,"LI"),
        gevent.spawn(apple,"HO"),
        ])

if __name__ == "__main__":
    main()

协程多任务实现2:yield实现协程(yield最底层,最灵活,是python自带的模块)

import time

def to_activate():
    yield
    print("吃早饭")
    print("读文档")
    yield
    print("吃中午饭")
    print("写程序")
    yield
    print("吃晚饭")
    print("解bug")

def to_sleep():
    yield
    print("午睡")
    yield
    print("晚休")

def main():
    print("程序员的一天")
    activate = to_activate()
    sleep = to_sleep()

    # 利用yield开始在两个函数间跳转
    next(activate)
    next(sleep)
    next(activate)
    next(sleep)
    next(activate)

    print("程序员的一天结束了")



if __name__ == "__main__":
    main()


协程多任务实现3:greenlet实现协程(模块须通过pip单独安装,个人感觉这个模块封装的并不够好,所以放到最后,仅供了解)

sudo pip3 install greenlet


import time
from greenlet import greenlet

activate = None
sleep = None

def to_activate():
    print("吃早饭")
    print("读文档")
    sleep.switch()
    print("吃中午饭")
    print("写程序")
    print("吃晚饭")
    print("解bug")

def to_sleep():
    print("午睡")
    activate.switch()
    print("晚休")

def main():
    global activate
    global sleep
    print("程序员的一天")
    activate = greenlet(to_activate)
    sleep = greenlet(to_sleep)

    #从activate开始执行
    activate.switch()
    print("程序员的一天结束了")



if __name__ == "__main__":
    main()

小结

  • 线程与进程相比,占用资源更少,但线程依赖于进程,一个进程可以有多个线程,进程完成任务依赖于内部的线程;
  • 协程解决了线程之间争用资源引发的资源浪费,所以协程比线程占用的资源更少.
目录
相关文章
|
5月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
消息中间件 并行计算 安全
进程、线程、协程
【10月更文挑战第16天】进程、线程和协程是计算机程序执行的三种基本形式。进程是操作系统资源分配和调度的基本单位,具有独立的内存空间,稳定性高但资源消耗大。线程是进程内的执行单元,共享内存,轻量级且并发性好,但同步复杂。协程是用户态的轻量级调度单位,适用于高并发和IO密集型任务,资源消耗最小,但不支持多核并行。
279 1
|
10月前
|
Python
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
390 20
|
存储 Java 数据库
如何处理线程池关闭时未完成的任务?
总之,处理线程池关闭时未完成的任务需要综合考虑多种因素,并根据实际情况选择合适的处理方式。通过合理的处理,可以最大程度地减少任务丢失和数据不一致等问题,确保系统的稳定运行和业务的顺利开展。
575 64
|
消息中间件 监控 Java
线程池关闭时未完成的任务如何保证数据的一致性?
保证线程池关闭时未完成任务的数据一致性需要综合运用多种方法和机制。通过备份与恢复、事务管理、任务状态记录与恢复、数据同步与协调、错误处理与补偿、监控与预警等手段的结合,以及结合具体业务场景进行分析和制定策略,能够最大程度地确保数据的一致性,保障系统的稳定运行和业务的顺利开展。同时,不断地优化和改进这些方法和机制,也是提高系统性能和可靠性的重要途径。
326 62
|
11月前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
409 17
|
11月前
|
消息中间件 调度
如何区分进程、线程和协程?看这篇就够了!
本课程主要探讨操作系统中的进程、线程和协程的区别。进程是资源分配的基本单位,具有独立性和隔离性;线程是CPU调度的基本单位,轻量且共享资源,适合并发执行;协程更轻量,由程序自身调度,适合I/O密集型任务。通过学习这些概念,可以更好地理解和应用它们,以实现最优的性能和资源利用。
369 11
|
10月前
|
数据采集 Java 数据处理
Python实用技巧:轻松驾驭多线程与多进程,加速任务执行
在Python编程中,多线程和多进程是提升程序效率的关键工具。多线程适用于I/O密集型任务,如文件读写、网络请求;多进程则适合CPU密集型任务,如科学计算、图像处理。本文详细介绍这两种并发编程方式的基本用法及应用场景,并通过实例代码展示如何使用threading、multiprocessing模块及线程池、进程池来优化程序性能。结合实际案例,帮助读者掌握并发编程技巧,提高程序执行速度和资源利用率。
506 0
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
259 12
|
存储 消息中间件 人工智能
进程,线程,协程 - 你了解多少?
本故事采用简洁明了的对话方式,尽洪荒之力让你在轻松无负担的氛围中,稍微深入地理解进程、线程和协程的相关原理知识
129 2
进程,线程,协程 - 你了解多少?

推荐镜像

更多