python 多任务详解

news2024/12/23 18:44:51

  • 1、线程
    • ① 函数方式创建线程
    • ② 自定义类创建线程
  • 2、队列
    • ① 普通队列 Queue
    • ② 堆栈 LifoQueue
    • ③ 优先级 PriorityQueue
  • 3、互斥锁
  • 4、进程
    • ① 函数方式创建进程
    • ② 类方式创建进程
    • ③ 进程中的队列
    • ④ 进程间通信
  • 5、 线程与进程区别
    • ① 线程共享全局变量,进程不共享
    • ② 所有的线程都在同一个进程中
    • ③ 线程开销小,但不利于资源的管理和保护,进程相反
  • 6、进程池
    • ① 案例1:
    • ② 进程池间通信
      • 案例1:

1、线程

线程是进程的一个实体,是cpu调度和分派的基本单位。
Python中的线程是轻量级执行单元,可以在同一进程中并发执行。Python中的线程由threading模块提供支持。线程的创建可以通过直接实例化Thread类或者继承Thread类并重写run()方法来实现。

import threading # 导入线程包
def f_a(): # 创建函数a
	pass
thread_1 = threading.Thread(target=f_a,args=(),kwargs={}) # 创建线程
thread_1.start() # 开始执行线程

① 函数方式创建线程

简单创建线程测试

import threading
import time

def task_1(print1):
    while 1:
        print(print1)
        time.sleep(1)
print1 = "woshi 1111111111"
thread_1 = threading.Thread(target=task_1,args=(print1,)) # 通过 args/kwargs传入元组/字典进行传参
thread_1.start()

while 1:
    print("hello")
    time.sleep(1)

![在这里插入图片描述](https://img-blog.csdnimg.cn/7f8f0eeb785049c0ac5b759b239e76fe.png

② 自定义类创建线程

import threading # 导入线程包

class C_1(threading.Thread): # 自定义 并继承threading.Thread类
	def run(self): # 添加run()方法,start()自动调用该方法
		pass

thread_1 = C_1() 
thread_1.start() # 此处调用thread_1.run()方法并不能生成线程

2、队列

Python中的队列是一种数据结构,用于在多个线程之间安全地传递数据。队列的实现可以使用queue模块提供的类。

import queue

① 普通队列 Queue

先进先出

import queue
q1 = queue.Queue()
q1.put('xxx')
q1.get() # 如果当前队列没有数据 则会堵塞

在这里插入图片描述

② 堆栈 LifoQueue

后进先出

import queue
q1 = queue.LifoQueue()
q1.put('xxx')
q1.get() # 如果当前队列没有数据 则会堵塞

在这里插入图片描述

③ 优先级 PriorityQueue

import queue
q1 = queue.PriorityQueue()
q1.put((1,'xxx')) # 参数需要为元组,第一个元素表示优先级,数字越小优先级越高,第二个元素表示数据
q1.get() # 如果当前队列没有数据 则会堵塞

在这里插入图片描述

3、互斥锁

互斥锁用于控制多个线程之间对共享资源的访问。互斥锁可以确保在任何时刻只有一个线程可以访问共享资源,从而避免了多个线程同时修改共享资源而导致的数据竞争和不一致问题。Python中的互斥锁可以使用threading模块提供的Lock类来实现。在使用互斥锁时,需要首先获取锁,然后访问共享资源,最后释放锁。如果在获取锁时发现锁已经被其他线程占用,则当前线程会被阻塞,直到锁被释放为止。

mutex = threading.Lock() # 创建锁
mutex.acquire() # 上锁
# xxxxxx # 上锁代码
mutex.release() # 释放锁,同一锁被释放前,不能再次上锁

4、进程

指在操作系统中正在运行的代码+所需系统资源实例称之为进程。
Python 通过 multiprocessing 模块来支持多进程编程,可以使用该模块创建、管理和控制多个进程。

① 函数方式创建进程

import multiprocessing # 导入进程包
def p_a(): # 创建函数a
	pass

process_1 = multiprocessing.Process(target=p_a,args=(),kwargs={}) # 创建子进程
process_1.start() # 启动子进程

② 类方式创建进程

import multiprocessing # 导入进程包

class Process1(multiprocessing.Process): # 自定义 并继承multiprocessing.Process类
    def run(self): # 添加run()方法,start()自动调用该方法
        pass

process_1 = Process1()
process_1.start()
import multiprocessing
import time

def p_1():
    while 1:
        print("i am p_1")
        time.sleep(1)

class Process1(multiprocessing.Process):
    def run(self):
        while 1:
            print("i am process_1")
            time.sleep(1)


if __name__ == '__main__':
    process_1 = Process1()
    process_1.start()

    p1 = multiprocessing.Process(target=p_1)
    p1.start()

    while 1:
        print("i am main")
        time.sleep(1)

在这里插入图片描述

③ 进程中的队列

在multiprocessing模块中,队列(Queue)是一种用于在多个进程之间安全地传递数据的数据结构。队列的实现可以使用multiprocessing模块提供的Queue类。与Python中的线程队列类似,multiprocessing中的队列也提供了线程安全的入队和出队操作,可以安全地在多个进程之间共享。需要注意的是,在使用multiprocessing中的队列时,由于不同进程之间的内存空间是相互独立的,因此需要使用特殊的进程锁(Lock)来确保数据的同步和正确性。

import multiprocessing
p_q = multiprocessing.Queue(x) # 创建一个进程队列p_q,最多可以接收x条put
p_q.put("aaa")
p_q.full() # 判断队列是否满,返回True/False
p_q.empty() # 判断队列是为空,返回True/False
p_q.get()
import multiprocessing
p_q = multiprocessing.Queue(4)

print("当前队列是否为空:",p_q.empty()) # 使用p_q.empty()判断队列是否为空
p_q.put("aaa")
print("当前队列是否为空:",p_q.empty())
p_q.put("bbb")
p_q.put("ccc")
p_q.put("ddd")
print("当前队列是否已满:",p_q.full()) # 使用p_q.full()判断队列是否已满

try:
    p_q.put("eeeeeee",timeout=2) # 等待两秒后put进入队列,使用try except抛出异常
except:
    print("当前队列已满,队列里面有:",p_q.qsize()) # 使用p_q.qsize()查看队列当前数量

try:
    p_q.put_nowait("ffff") # 立刻put到当前队列,不等待,无法进入则抛出异常
except:
    print("当前队列已满,队列里面有:",p_q.qsize())


在这里插入图片描述

④ 进程间通信

案例1:进程间通信有管道、socket、队列等方法,此处演示队列方法

import multiprocessing
import time

def task1(q):
    for i in ["aa","bbb","cc","dd","eeeeee"]:
        q.put(i)
        print(i,'已进入队列')
        time.sleep(1)

def task2(q):
    while 1:
        if not q.empty():
            qi = q.get()
            print("已从队列取出",qi)
            time.sleep(1)
        else:
            break

if __name__ == '__main__':

    q = multiprocessing.Queue()

    p1 = multiprocessing.Process(target=task1,args=(q,))
    p2 = multiprocessing.Process(target=task2, args=(q,))
    p1.start()
    p2.start()

![在这里插入图片描述](https://img-blog.csdnimg.cn/ad03082922be469fadf0b217d45bef52.png

5、 线程与进程区别

进程跟线程,都可以完成多任务
进程:一台电脑上登录多个QQ
线程:一个QQ中打开多个聊天窗口

① 线程共享全局变量,进程不共享

当一个进程结束时,不会对另一个进程产生影响

import multiprocessing
import time
A=1
def p_1():
    global A
    A=999
    print("p_1结果是:"+str(A))


def p_2():

    print("p_2结果是:"+str(A))


if __name__ == '__main__':
    p1 = multiprocessing.Process(target=p_1)
    p2 = multiprocessing.Process(target=p_2)
    p1.start()
    time.sleep(2)
    p2.start()

此处A=999并没有传入p_2()
在这里插入图片描述

② 所有的线程都在同一个进程中

③ 线程开销小,但不利于资源的管理和保护,进程相反

6、进程池

由于进程创建跟关闭的开销大,可以使用进程池来让进程 “重复利用”

# 主进程
import multiprocessing 

pool = multiprocessing.Pool(x) # 创建进程池,表示最多有x个进程同时运行

def p(num):
    pass

# 往进程池中新增子进程,池满则等待前面进程结束后再往池里新增
for i in range(10):
    pool.apply_async(p,(i,))

pool.close() # 关闭进程池
pool.join() # 主进程不会等待子进程结束再结束,需要添加pool.join()等待子进程全部结束后,先回收结束的子进程资源再开始主进程往下运行

① 案例1:

这个案例说明,从进程pid可以看出,进程可以重复利用,不需要重新新建进程与关闭进程

import multiprocessing
import time
import os

def p(num):
    print("现在执行的是子进程",num)
    print("子进程号是:",os.getpid())
    time.sleep(1)


if __name__ == "__main__":
    print("主进程号是:",os.getpid())
    pool = multiprocessing.Pool(2)
    for i in ['AA','BB','CC','DD','EE','ff']:
        pool.apply_async(p,(i,))


    pool.close()
    pool.join()
    print("主进程 {} 结束".format(os.getpid()))

在这里插入图片描述

② 进程池间通信

使用进程池中的queue

案例1:

import multiprocessing
q = multiprocessing.Manager().Queue() # 使用进程池中的queue
import multiprocessing
import os
import time

def task1(queue):
    print("我是子进程1,进程号是:",os.getpid())
    for i in ['AA','BB','CC','DD','EE','ff']:
        queue.put(i)
        print("从队列插入:",i)
        time.sleep(2)


def task2(queue):
    print("我是子进程2,进程号是:",os.getpid())
    
    while 1:
        try:
            print("从队列取出:",queue.get(timeout=3))
            time.sleep(1)
        except multiprocessing.TimeoutError:
            print("Queue is empty for 5 seconds, exiting...")
            break

if __name__ == "__main__":
    print("我是主进程,进程号是:",os.getpid())

    pool_queue = multiprocessing.Manager().Queue() # 创建进程池队列

    pool = multiprocessing.Pool(2) # 创建进程池

    pool.apply_async(task1,(pool_queue,)) # 将task1加入进程池
    time.sleep(1)
    pool.apply_async(task2,(pool_queue,)) # 将task2加入进程池

    pool.close()
    pool.join()
    print("主进程 {} 结束".format(os.getpid()))

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/692819.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tomcat部署相关问题汇总

一.Jar包冲突 由于项目当中依赖了一些框架,而这些框架无法直接修改时,就直接本地代码写了一个同名同包路径的类,可以直接覆盖框架的类,但是心里不免有疑问,为啥本地写的同名同路径的类,可以覆盖三方框架的类呢&#x…

分层解耦相关知识点

这里写目录标题 三层架构简介具体案例原始代码DAO层代码service层controller层总结 分层解耦思想IOC&DI 入门简介控制反转依赖注入 IOC详解详细种类 DI详解 三层架构 简介 具体案例 原始代码 DAO层代码 分别是一个接口实现类以及一个接口,用接口是为了提高程…

Python pyqt5 qss美化窗口

效果 QSS QWidget#widget{background-color:#eef0f6;border-left:0.5px solid lightgray;border-right:0.5px solid lightgray;border-top:0.5px solid lightgray;border-bottom:0.5px solid #e5e5e5;border-top-left-radius: 5px;border-top-right-radius: 5px;}QWidget#widge…

Google测试之道丨如何从角色出发谈谈漫游测试?

谈到“漫游测试”,想必大多数人想起的都是James A.whittaker提出的全局探索性测试方法。他将软件测试比如为城市旅游,并划分了不同的区域(如:商业区、历史区、娱乐区等等),将测试人员比喻为旅游者进行城市旅…

vue3组件通信之pinia

简述 在vue3,vue的状态管理也迎来了新的变更,在vue3使用新的组件pinia来代理原有的vuex。pinia相比vuex,功能收敛了不少,比如不直接暴露setter方式,外部直接修改数据 两者的概念区别 vuex:集中式管理状态容器,可以实…

java之路—— Spring IOC 的详解与基本应用

创作不易,给个小支持一下呗 文章目录 前言一、IOC 基本概念二、理解IOC三、基本步骤 前言 首先在了解ioc之前,我们要先了解Spring的基本概念。 Spring是一个开源的Java应用程序开发框架,它提供了一套全面的解决方案,用于开发企业…

从此告别网速慢,轻松掌握浏览器缓存知识点!

文章目录 I. 介绍浏览器缓存的作用提高网页加载速度减少网络带宽消耗优化用户体验 II. 浏览器缓存的原理缓存机制缓存分类1. 强缓存2. 协商缓存 III. 强缓存缓存操作流程缓存过期机制如何设置强缓存 IV. 协商缓存304 Not Modified状态码缓存操作流程如何设置协商缓存 V. 缓存失…

kubernetes核心概念 Pod

Kubernetes集群核心概念 Pod 一、工作负载(workloads) 参考链接:https://kubernetes.io/zh/docs/concepts/workloads/ 工作负载(workload)是在kubernetes集群中运行的应用程序。无论你的工作负载是单一服务还是多个一同工作的服务构成&…

第2章-Java基本语法

Java基础知识图解 1. 关键字与保留字 关键字 Java保留字: 现有Java版本尚未使用, 但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字 goto 、 const 2. 标识符 Java 对各种变量、 方法和类等要素命名时使用的字符序列称为标识符…

Elasticsearch:增量快照如何工作?

作者:Lutf ur Rehman Elastic 提供许多由讲师指导的面对面和虚拟现场培训以及点播培训。 我们的旗舰课程是 Elasticsearch 工程师、Kibana 数据分析和 Elastic 可观测性工程师。 所有这些课程都会获得认证。如果你想更多了解这些认证方面的知识,请阅读文…

【CXP协议与CXP测试套件】

CXP协议 CoaXPress (简称CXP)是指一种采用同轴线缆进行互联的相机数据传输标准,主要用于替代之前的Camera Link协议,常见于科学相机、工业相机、医学图像、航空防务等场景。CXP是一个非对称的高速点对点串行传输协议,主要用于传输视频和静态…

GO 微信支付V3SDK回调踩坑

通过微信官网提示安装sdk外部库 SDK,工具 | 微信支付商户平台文档中心 下面只讲解微信支付回调部分 先成功下一单微信支付拿到支付回调的数据,方便后续调试 因为在go里面打印请求参数不方便我使用的php打印全部参数, 圈起来的部分是我们需…

centos8.x系统安装K8S,kubernetes集群v1.23.9,docker支持的最后一个版本

1. 部署环境主机(条件说明) 卸载podman,centos默认安装了podman容器(不管有没有,执行下总没错),可能与docker存在冲突 #环境准备 master 192.168.186.128 CentOS Linux release 8.5 (Core) n…

软件接口测试是什么?有哪些好用的接口测试工具?

在软件开发中,接口是不可避免的。软件接口测试是一种验证应用程序接口是否按照设计规范进行交互和协作的测试方法。接口测试是将模块之间的接口连接在一起以进行完整系统测试的关键部分。 当软件开发过程中不同模块之间需要数据交互,采用接口协议来实现…

Qt之事件过滤器讲解并且实现快捷键切换鼠标焦点

目录 1、需求背景2、使用Qt键盘事件3、安装事件过滤器4、事件处理级别 1、需求背景 现在有一个类似于下方图的ui,用户需要在输入前一行内容后,需要摁下指定案件能够跳转到下一行继续进行输入。 2、使用Qt键盘事件 一种更为直接的解决方案是子类化QLi…

【SpringCloud-6】Config配置中心

集群环境下,服务节点很多,我们不可能对每个服务都维护一套自己的配置,有修改时把每个节点都改一遍。 所以需要一个公共的配置文件,并且还能实现动态刷新。 在springcloud中,springcloud config组件就是一个配置中心&…

8年测试老鸟整理,软件测试面试问题-初中级,全覆盖问题...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 一般测试面试分为…

pytorch动态调整学习率torch.optim.lr_scheduler import MultiStepLR

from torch.optim.lr_scheduler import MultiStepLR 简单来说,就是分阶段调整学习率. 用法: model ANet(classes5) #加载模型 optimizer optim.SGD(params model.parameters(), lr0.05) #优化方法使用SGD#在指定的epoch值&#x…

极端交换————晴问算法

文章目录 1 题目2 思路3 实现 1 题目 2 思路 以此比较最大值、最小值&#xff0c;记录最大、最小值以及其下标位置&#xff0c;结束遍历后&#xff0c;交换其位置。 3 实现 #include<iostream> using namespace std;int main(){int n;scanf("%d", &n);i…

30分钟,认识 html 本质

30分钟&#xff0c;认识 html 本质 html 是什么&#xff1f;html 起源html 发展标签分类空间占用方式布局文本修饰流媒体标签 预定义符号 Symbols弃用的部分标签学习 html html 是什么&#xff1f; HTML的英文全称是 Hyper Text Markup Language&#xff0c;即超文本标记语言。…