12 python多任务:进程线程协程

本文详细介绍了Python中实现多任务的三种方式:多线程、多进程和协程。多线程通过threading模块实现,包括线程同步的互斥锁,以及死锁的概念。多进程使用multiprocessing模块,通过fork函数和进程池实现,进程间通信可使用队列和管道。协程是更轻量级的多任务解决方案,greenlet和gevent库提供支持。文章还讨论了GIL(全局解释器锁)对Python多线程的影响以及如何应对。
摘要由CSDN通过智能技术生成

Mac OS X,UNIX,Linux,Windows等,都是多任务操作系统即操作系统可以同时运行多个任务。对于操作系统来说,一个任务就是一个进程(Process),一个任务可分为多个子任务。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,这些“子任务”称为子进程。一个进程至少有一个线程。进程是系统资源分配的基本单位,线程操作系统调度的基本单元。

操作系统的设计,可以归结为三点:

  • 以多进程形式,允许多个任务同时运行;
  • 以多线程形式,允许将单个任务分成多个子任务运行;
  • 提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。

多任务

  • 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任务“一起”执行(实际上总有一些任务不在执行,因为切换任务的速度相当快,看上去一起执行而已)

  • 并行:指的是任务数小于等于cpu核数,即任务真的是一起执行的

  • 单核cpu实现多任务,时间片轮转方式。并发,假的多进程。

  • 多核cpu实现多任务:并行,真的多进程。

1. 多线程

python可使用多线程实现多任务。python提供了thread模块和threading模块,thread是低级模块,后者对其进行了封装。一般我们使用threading模块实现多线程。一个进程至少启动一个线程,该线程称为主线程(MainThread)。主线程可以启动新的线程即子线程。

实现多线程一般有两种方式:

1.1 threading.Thread类创建线程

Thread类语法结构如下:Thread([group [, target [, name [, args [, kwargs]]]]])

  • target:如果传递了函数的引用,子进程就执行函数内的代码
  • name:给线程设定一个名字,可以不设定
  • args:给target指定的函数传递的参数,以元组的方式传递
  • kwargs:给target指定的函数传递命名参数
  • group:指定线程组,大多数情况下用不到

Thread类创建的实例对象的常用方法:

  • start():创建并启动子线程
  • join([timeout]):是否等待子线程执行结束或等待多少秒
  • is_alive():判断进程子进程是否还在活着
from threading import Thread
import time

def info(num):
    for x in range(3):
        print("--------线程%d执行-------" % num)
        time.sleep(1)
    
if __name__ == "__main__":
    t1 = Thread(target=info, args=(1,))
    t2 = Thread(target=info, args=(2,))
    t1.start() 
    t2.start()

# 执行结果
--------线程1执行-------
--------线程2执行-------
--------线程1执行-------
--------线程2执行-------
--------线程1执行-------
--------线程2执行-------
from threading import Thread
import time

def info(num):
    for x in range(3):
        print("--------线程%d执行-------" % num)
        time.sleep(1)
    
if __name__ == "__main__":
    t1 = Thread(target=info, args=(1,))
    t2 = Thread(target=info, args=(2,))
    t1.start() 
    t1.join()  # join()方法阻塞其他线程,直到t1线程执行完才会执行其他进程  
    # time.sleep(5)  (也可使用时间延时控制进程执行顺序)
    t2.start()

# 执行结果
--------线程1执行-------
--------线程1执行-------
--------线程1执行-------
--------线程2执行-------
--------线程2执行-------
--------线程2执行-------
1.2 自定义线程类

自定义线程类应继承于Threading类。线程实例调用start()方法创建并启动线程时,会自动调用run()方法。因此编写线程类时,需要将执行的功能代码封装到run()内部。

# 自定义线程类
import time
from threading import Thread

class Mythread(Thread):
    
    def __init__(self, num):
        self.num = num
        return super().__init__()
    
    def run(self):
        for x in range(3):
            print("-----线程%d执行-----" % self.num)
            time.sleep(0.5)
            
t1 = Mythread(1)
t2 = Mythread(2)
t1.start()  # 自动调用run()方法执行功能代码
t2.start()

# 执行结果
-----线程1执行-----
-----线程2执行-----
-----线程2执行-----
-----线程1执行-----
-----线程2执行---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值