当前位置: 首页 > news >正文

多线程和多进程的快速入门

多线程和多进程的快速入门

学习自:莫烦Python www.mofanpy.com

Threading - 多线程运算python程序

​ 多线程的简单理解:把数据分成很多段,将每一段数据放入一个线程,将所有的线程同时开始,大大的节省了运算时间。相当于:请一个人来工作一件事和请很多人来工作一件事

Threading 可以分配python分批量在同一时间做事情,但是Threading只能是在一个py脚本中

添加一个线程的案例

import threading#def main():
#    print(threading.active_count()) # 查看现在激活线程的数量
#    print(threading.enumerate()) # 查看当前的threading都是什么
#    print(threading.current_thread()) # 查看我运行这个函数程序的时候 对应的threading是什么def thread_job():print('This is a thread of %s' % threading.current_thread()) # 查看我运行这个函数程序的时候 对应的threading是什么def main():thread = threading.Thread(target=thread_job,) # 添加线程  这个线程做什么由target指定thread.start() # 添加一个线程后,要启动线程,才能让这个线程开始工作if __name__ == '__main__':main()

程序运行的结果为:

This is a thread of <Thread(Thread-1, started 6300)>

threading中的join的功能

由于多线程是同石进行运行的线程任务,如果某些时刻你想等待所有的线程都运行完,然后开始某些操作,这个时候需要在这个操作前对每个线程使用join操作

join操作是等待threading线程运行完

import threading
import time
def thread_job():print('T1 start\n')for i in range(10): time.sleep(0.1) # 睡一秒 print('T1 finish\n')def T2_job():print('T2 start\n')print('T2 finish\n')def main():added_thread = threading.Thread(target=thread_job, name='T1') # name为给线程命名thread2 = threading.Thread(target=T2_job, name='T2')added_thread.start()thread2.start()thread2.join()added_thread.join()print('all done\n')if __name__ == '__main__':main()

不加join的结果如下:

T1 startT2 start
all doneT2 finishT1 finish

加join的结果如下:

T1 startT2 startT2 finishT1 finishall done

多线程搭配Queue功能

多线程无返回值,所以要把运算出来的结果放在一个长的队列中,对每一个线程的队列到主线程中拿出来,以便做继续的运算。

import threading
import time
from queue import Queuedef job(l,q):# 对每一个列表中的值做平方运算for i in range(len(l)):l[i] = l[i]**2q.put(l)def multithreading():q = Queue() # 定义队列threads = [] # 用来存储所有的线程data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]for i in range(4): # 定义四个线程 计算大列表中的四个小列表t = threading.Thread(target=job, args=(data[i], q)) # args用来给线程 传递参数t.start() # 启动线程threads.append(t) # 将每个小列表的计算线程 存储到线程列表中for thread in threads: thread.join() # 等到所有的线程运行完 再继续操作results = []for _ in range(4): results.append(q.get()) # 将每个线程运算的结果 保存print(results)if __name__ == '__main__':multithreading()

该程序的结果如下:

[[1, 4, 9], [9, 16, 25], [16, 16, 16], [25, 25, 25]]

多线程的效率分析

多线程的全局控制并不是把任务平均的分配个每一个线程 ,python只能让一个线程在某一时刻运算一个东西,然后不停的切换线程,让你误以为这些线程是在相同时刻在运算。 (学过操作系统应该会很容易理解多线程的并发运算)

下面实力代码中:

normal方法:对四倍的l列表执行累加运算

multithreading多线程方法:将四倍的l列表分为四份,用四个多线程同时处理

import threading
from queue import Queue
import copy
import timedef job(l, q):res = sum(l)q.put(res)def multithreading(l):q = Queue()threads = []for i in range(4):t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)t.start()threads.append(t)[t.join() for t in threads]total = 0for _ in range(4):total += q.get()print(total)def normal(l):total = sum(l)print(total)if __name__ == '__main__':l = list(range(1000000))s_t = time.time()normal(l*4)print('normal: ',time.time()-s_t)s_t = time.time()multithreading(l)print('multithreading: ', time.time()-s_t)

程序的执行结果:

1999998000000
normal:  0.08538269996643066
1999998000000
multithreading:  0.08719158172607422

用了多线程比未用多线程的耗时反而多了

多线程与lock锁

锁的用法:当第一个线程处理完这一批数据得到一个初步的结果,然后再把这个结果拿去给第二个线程处理,这个时候就需要锁住第一个线程,等他处理完,再开始第二个线程

在要进行上锁的程序的前后设置锁

import threadingdef job1():global A, locklock.acquire() # 在要进行上锁的程序前 设置锁for i in range(10): # 对A进行10次累加1A += 1print('job1', A)lock.release() # 在要进行上锁的程序后 设置锁def job2():global A, locklock.acquire()for i in range(10): # 对A进行10次累加10A += 10print('job2', A)lock.release()if __name__ == '__main__':lock = threading.Lock() # 定义锁A = 0 # 定义一个全局变量   模拟共享内存t1 = threading.Thread(target=job1)t2 = threading.Thread(target=job2)t1.start()t2.start()t1.join()t2.join()

不加锁的程序结果: 两个线程同时运行,结果上为交替对A进行操作

job1 1
job1 2
job1 13
job2 12
job1 14
job2 24
job1 25
job2 35
job1 36
job2 46
job1 47
job2 57
job1 58
job2 68
job1 69
job2 79
job1 80
job2 90
job2 100
job2 110

加锁的程序结果: job1先上锁 待程序运行完后 解锁。此时job2再上锁 待程序运行完后 解锁

job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 10
job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 80
job2 90
job2 100
job2 110

Multiprocessing - 多进程运算python程序

​ 运用多核CPU处理器CPU运算python程序,一般只会用一个核来处理程序,但是现代计算器的处理器一般都是多核,如果不用白白的浪费,可以将其运用起来加速程序的处理。

多线程实际上还是同一个时间处理一个线程(并发轮转调度),而多核完全避免了这种情况,它会把任务平均分配给每一个核,每一个核都有单独的运算空间和运算能力,多核从一定程度上避免了多线程劣势。

创建进程

import multiprocessing as mpdef job(q):print("进程创建", q)if __name__ == '__main__':p1 = mp.Process(target=job, args=(q,))p1.start()

进程与Queue输出

将每一个核运算出来的结果放入到队列Queue中,等到所有的核运算完成后,再将结果从队列中取出,以便后续操作

import multiprocessing as mpdef job(q):res = 0for i in range(1000):res += i+i**2+i**3q.put(res) # 将运算后的值操作放入到队列if __name__ == '__main__':q = mp.Queue() # 定义队列p1 = mp.Process(target=job, args=(q,)) # 注意args 即使只有一个参数 也要写成(q,) 不然会报错 p2 = mp.Process(target=job, args=(q,))p1.start()p2.start()p1.join()p2.join()res1 = q.get() # 从队列中获取值res2 = q.get()print(res1+res2)

运行结果为:499667166000

进程池

进程池就是把所有要运行的东西放到一个池子里,python自己解决如何分配这些进程,如何分配运行出来的结果。

import multiprocessing as mpdef job(x): # 平方操作return x*xdef multicore():pool = mp.Pool(processes=2) # 默认的是你所有的核心, processes是指定想用的核的数量res = pool.map(job, range(10)) # map 将range(10) 交给job,并将结果返回print(res)res = pool.apply_async(job, (2,)) # 只传入一个值给job   如果输入的是(2,3,4,5)会报错,因为只能传入一个值print(res.get()) # 使用get获取multi_res =[pool.apply_async(job, (i,)) for i in range(10)] # 利用迭代器 获取对多个值操作的结果print([res.get() for res in multi_res]) # 利用列表迭代获取if __name__ == '__main__':multicore()

程序运行的结果:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
4
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

多进程使用shared memory共享内存

为什么使用共享内存,不用全局变量?

因为多进程中传入全局变量给每个cpu,多进程对全局变量进行操作后传给其它进程是行不通的

import multiprocessing as mpvalue = mp.Value('i', 1)  #  i是整数 d是double小数 f是float小数等等
array = mp.Array('i', [1, 2, 3, 4]) # 只能是一维列表,不能是多维

value和array可以被每一个核读取,加载到内存

多进程与lock锁

锁的应用:

import multiprocessing as mp
import timedef job(v, num, l):l.acquire()for _ in range(10):time.sleep(0.1)v.value += numprint(v.value)l.release()def multicore(): l = mp.Lock() # 实例化锁v = mp.Value('i', 0) # 设立共享内存变量p1 = mp.Process(target=job, args=(v, 1, l)) p2 = mp.Process(target=job, args=(v, 3, l))p1.start()p2.start()p1.join()p2.join()if __name__ == '__main__':multicore()

加锁的结果为:

前面程序依次+1 后面程序依次+3

不加锁的结果为:

3 4 7 8 11 12这样两个多进程交替打印结果

多线程、多进程以及函数的效率对比

import multiprocessing as mp
import threading as td
import timedef job(q):res = 0for i in range(1000000):res += i+i**2+i**3q.put(res) # queuedef multicore():q = mp.Queue()p1 = mp.Process(target=job, args=(q,))p2 = mp.Process(target=job, args=(q,))p1.start()p2.start()p1.join()p2.join()res1 = q.get()res2 = q.get()print('multicore:' , res1+res2)def normal():res = 0for _ in range(2):for i in range(1000000):res += i+i**2+i**3print('normal:', res)def multithread():q = mp.Queue()t1 = td.Thread(target=job, args=(q,))t2 = td.Thread(target=job, args=(q,))t1.start()t2.start()t1.join()t2.join()res1 = q.get()res2 = q.get()print('multithread:', res1+res2)if __name__ == '__main__':st = time.time()normal()st1= time.time()print('normal time:', st1 - st)multithread()st2 = time.time()print('multithread time:', st2 - st1)multicore()print('multicore time:', time.time()-st2)

运行的结果:

# 不用进程和线程
normal: 499999666667166666000000
normal time: 0.75795578956604
# 多线程
multithread: 499999666667166666000000
multithread time: 0.7419922351837158
# 多进程
multicore: 499999666667166666000000
multicore time: 0.4487142562866211

多进程运算的时间明显由于另外两个,多线程的运算与什么都不做时间差不多,说明多线程对于某些运算还是存在明显的短板

相关文章:

多线程和多进程的快速入门

多线程和多进程的快速入门 学习自&#xff1a;莫烦Python www.mofanpy.com Threading - 多线程运算python程序 ​ 多线程的简单理解&#xff1a;把数据分成很多段&#xff0c;将每一段数据放入一个线程&#xff0c;将所有的线程同时开始&#xff0c;大大的节省了运算时间。相…...

【TensorFlow深度学习】经典卷积网络架构回顾与分析

经典卷积网络架构回顾与分析 经典卷积网络架构回顾与分析&#xff1a;从AlexNet到ResNet、VGGLeNet、ResNet、DenseNet的深度探索AlexNet ——深度学习的破冰点火VGGNet — 简洁的美ResNet — 深持续深度的秘钥DenseNet — 密集大成塔实战代码示例&#xff1a;ResNet-50模型结语…...

Salesforce推出Einstein 1 Studio:用于自定义Einstein Copilot并将人工智能嵌入任何CRM应用程序的低代码人工智能工具

一、关键要点 1. Salesforce管理员和开发人员现在可以在每个Salesforce应用程序和工作流程中构建、定制和嵌入人工智能&#xff0c;包括Einstein Copilot。 2. Einstein 1 Studio与数据云深度集成&#xff0c;通过对客户数据和元数据的全面理解&#xff0c;解锁并统一被捕获的…...

点赋科技:建设智能饮品高地,打造数字化产业先锋

在当今数字化时代的浪潮中&#xff0c;点赋科技以其敏锐的洞察力和卓越的创新能力&#xff0c;致力于建设智能饮品高地&#xff0c;打造数字化产业先锋。 点赋深知智能饮品机对于推动社会进步和满足人们日益增长的需求的重要性。因此&#xff0c;他们投入大量资源和精力&#x…...

ORACLE RAC的一些基本理论知识

一 . Oracle RAC 的发展历程 1. Oracle Parallel Server (OPS) 早期阶段&#xff1a;Oracle 6 和 7 Oracle Parallel Server&#xff08;OPS&#xff09;是 Oracle RAC 的前身。 通过多个实例并行访问同一个数据库来提高性能。 共享磁盘架构&#xff0c;利用分布式锁管理&am…...

CMake的作用域:public/private/interface

在 CMake 中&#xff0c;public、private和 interface是用来指定目标属性的作用域的关键字&#xff0c;这三个有什么区别呢&#xff1f;这些关键字用于控制属性的可见性和传递性&#xff0c;影响了目标之间的依赖关系和属性传递。 public 如果在一个目标上使用 public关键字时…...

设计模式基础知识点(七大原则、UML类图)

Java设计模式&#xff08;设计模式七大原则、UML类图&#xff09; 设计模式的目的设计模式七大原则单一职能原则&#xff08;SingleResponsibility&#xff09;接口隔离原则&#xff08;InterfaceSegreation&#xff09;依赖倒转原则&#xff08;DependenceInversion&#xff0…...

Android开机动画的结束过程BootAnimation(基于Android10.0.0-r41)

文章目录 Android 开机动画的结束过程BootAnimation(基于Android10.0.0-r41) Android 开机动画的结束过程BootAnimation(基于Android10.0.0-r41) 路径frameworks/base/cmds/bootanimation/bootanimation_main.cpp init进程把我们的BootAnimation的二进制文件拉起来了&#xf…...

微软远程连接工具:Microsoft Remote Desktop for Mac 中文版

Microsoft Remote Desktop 是一款由微软开发的远程桌面连接软件&#xff0c;它允许用户从远程地点连接到远程计算机或虚拟机&#xff0c;并在远程计算机上使用桌面应用程序和文件。 下载地址&#xff1a;https://www.macz.com/mac/5458.html?idOTI2NjQ5Jl8mMjcuMTg2LjEyNi4yMz…...

【安规介绍】

文章目录 一、基础知识安规上的六类危险的防护&#xff1a;安全电压漏电流接触电流能量问题&#xff1a;火灾问题&#xff1a;热问题结构问题阻燃等级绝缘等级&#xff1a;对接地系统的要求&#xff1a;结构要求:电气要求&#xff1a; 二、设计的关键电气绝缘距离电气爬电距离:…...

[sylar]后端学习:配置环境(一)

1.介绍 基于sylar大神的C高性能后端网络框架来进行环境配置和后续学习。网站链接&#xff1a;sylar的Linux环境配置 2.下载 按照视频进行下载&#xff0c;并进行下载&#xff0c;并最好还要下载一个vssh的软件。可以直接在网上搜索即可。 sylar_环境配置&#xff0c;vssh下…...

XDMA原理及其应用和发展

XDMA原理 XDMA的主要原理是通过直接访问主机内存&#xff0c;实现数据的快速传输。在传统的DMA&#xff08;Direct Memory Access&#xff09;技术中&#xff0c;数据传输需要经过CPU的干预&#xff0c;而XDMA可以绕过CPU&#xff0c;直接将数据从外设读取到主机内存或者从主机…...

携程梁建章:持续投资创新与AI,开启旅游行业未来增长

5月30至31日&#xff0c;携程集团在上海和张家界举办Envision 2024全球合作伙伴大会&#xff0c;邀请超50个国家和地区的1600余名外籍旅游业嘉宾与会&#xff0c;共同探讨中国跨境旅游市场发展机遇&#xff0c;讲好中国故事。 携程国际业务增速迅猛&#xff0c;创新与AI解锁未…...

【网络安全的神秘世界】在win11搭建pikachu靶场

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 下载pikachu压缩包 https://github.com/zhuifengshaonianhanlu/pikachu 下载好的pikachu放在phpstudy_pro/www目录下 创建pikachu数据库 打开phpstudy软件…...

基于Java的零食管理系统的设计与实现(论文+源码)_kaic

摘 要 随着科技的进步&#xff0c;以及网络的普及&#xff0c;都为人们的生活提供了极大的方便。因此&#xff0c;在管理”三姆”宿舍在线零食商店时&#xff0c;与现代的网络联系起来是非常必要的&#xff0c;本次设计的系统在研发过程中应用到了Java技术&#xff0c;这在一定…...

【案例实操】银河麒麟桌面操作系统实例分享,V10SP1重启后网卡错乱解决方法

1.问题现象 8 个网口&#xff0c; 命名从 eth1 开始到 eth8。 目前在系统 grub 里面加了 net.ifnames0 biosdevname0 参数&#xff0c; 然后在 udev 规则中加了一条固定网卡和硬件 pci 设备号的规则文件。 最后在 rc.local 中加了两条重新安装网卡驱动的命令&#xff08; rmmod…...

初级前端开发岗

定位&#xff1a; 日常任务的辅助执行者&#xff0c;前端基础建设的参与者。 素质要求&#xff1a; 是否遵循部门敏捷流程、规范、P0制度&#xff1b;具备良好的沟通和协作能力;负责日常迭代任务的落地执行;拥有较强的执行力&#xff0c;能够灵活解决问题; 职责&#xff1a…...

颠仆流离学二叉树2 (Java篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…...

柏林自由大学研究团队《Ecology Letters 》揭示AMF在植物对全球变化响应的作用

全球环境变化正在影响陆生植物生长。植物已经进化出各种策略来应对这些挑战&#xff0c;其中之一是与丛枝菌根真菌(AMF)形成共生关系(高达80%的陆生植物物种)。AMF为寄主植物提供各种益处&#xff0c;例如营养吸收、耐受性、食草动物防御和抗病能力&#xff0c;以换取糖和脂质(…...

libevent源码跨平台编译(windows/macos/linux)

1.windows编译: 克隆: git clone https://github.com/libevent/libevent.git 克隆成功 生成makefile 生成成功 默认不支持OpenSSL,MbedTLS,ZLIB这三个库 编译: cmake --build . --config release...

idea+tomcat+mysql 从零开始部署Javaweb项目(保姆级别)

文章目录 新建一个项目添加web支持配置tomcat优化tomcat的部署运行tomcatidea数据库连接java连接数据库 新建一个项目 new project&#xff1b;Java&#xff1b;选择jdk的版本&#xff1b;next&#xff1b;next&#xff1b;填写项目名字&#xff0c;选择保存的路径&#xff1b;…...

LeetCode 每日一题 2024/5/27-2024/6/2

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 5/27 2028. 找出缺失的观测数据5/28 2951. 找出峰值5/29 2981. 找出出现至少三次的最长特殊子字符串 I5/30 2982. 找出出现至少三次的最长特殊子字符串 II5/31 2965. 找出缺…...

BOOST_SREATCH

BOOST Boost是一个由C社区开发的开源库&#xff0c;为C语言标准库提供扩展。这个库由C标准委员会库工作组成员发起&#xff0c;旨在提供大量功能和工具&#xff0c;帮助C开发者更高效地编写代码。Boost库强调跨平台性和对标准C的遵循&#xff0c;因此与编写平台无关&#xff0…...

MySQL学习——获取数据库和表格的信息

如果忘记了数据库或表的名称&#xff0c;或者不确定给定表的结构&#xff08;例如&#xff0c;其列的名称&#xff09;&#xff0c;该怎么办呢&#xff1f;MySQL通过几个语句解决了这个问题&#xff0c;这些语句提供了有关它支持的数据库和表的信息。 你之前已经看过SHOW DATA…...

Go语言redis框架 — go-redis

https://zhuanlan.zhihu.com/p/645669818 一、简述 1. API友好&#xff0c;命令名称和参数与Redis原生命令一致&#xff0c;使用简单方便。 2. 支持完整的Redis命令集&#xff0c;覆盖了字符串、哈希、列表、集合、有序集合、HyperLogLog等数据结构。 3. 支持连接池&#x…...

C++ | Leetcode C++题解之第125题验证回文串

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isPalindrome(string s) {int n s.size();int left 0, right n - 1;while (left < right) {while (left < right && !isalnum(s[left])) {left;}while (left < right && !isalnu…...

Spring创建对象的多种方式

一、对象分类 简单对象&#xff1a;使用new Obj()方式创建的对象 复杂对象&#xff1a;无法使用new Obj()方式创建的对象。例如&#xff1a; 1. AOP创建代理对象。ProxyFactoryBean; 2. Mybatis中的SqlSessionFactoryBean; 3. Hibernate中的SessionFactoryBean。二、创建对象方…...

宝塔部署前后端分离项目手册

文章目录 安装宝塔安装环境开始部署1. 前端Vue项目1.先本地启动前端项目&#xff08;记住端口号&#xff09;2.打包前端项目3.上传前端项目4.创建PHP站点5.安全里开放端口号6.测试前端 2. 后端boot项目1. 先在本地跑起来2.修改数据库的配置信息3. 项目打包4. nohup启动项目4.1 …...

Leetcode 第 397 场周赛题解

Leetcode 第 397 场周赛题解 Leetcode 第 397 场周赛题解题目1&#xff1a;3146. 两个字符串的排列差思路代码复杂度分析 题目2&#xff1a;思路代码复杂度分析 题目3&#xff1a;3148. 矩阵中的最大得分思路代码复杂度分析 题目4&#xff1a;3149. 找出分数最低的排列思路代码…...

Python+Selenium自动化测试项目实战

第 1 章 自动化测试 1.1、自动化测试介绍 自动化测试就是通过自动化测试工具帮我们打开浏览器&#xff0c;输入网址&#xff0c;输入账号密码登录&#xff0c;及登录后的操作&#xff0c;总的说来自动化测试就是通过自动化测试脚本来帮我们从繁琐重复的手工测试里面解脱出来&…...