Python并发编程
2021-06-03 05:01
标签:range 核心 就是 数据类型 process linux服务 ps aux amp wc -l 并发执行-并发编程 Python并发编程 标签:range 核心 就是 数据类型 process linux服务 ps aux amp wc -l 原文地址:https://www.cnblogs.com/ytwang/p/14680451.html1.物理机
01.Windows
NumberOfCores
NumberOfLogicalProcessors
cpu个数 是指物理上安装了几个cpu,一般的个人电脑是安装了1个cpu
cpu内核数 是指物理上,一个cpu芯片上集成了几个内核单元,现代cpu都是多核的。
cpu线程数 是指逻辑上处理单元,这个技术是Intel的超线程技术,它让操作系统识别到有多个处理单元
02.Linux服务器
-- 正在运行的程序都会在/proc
CPU的信息
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq
# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l
内存
cat /proc/meminfo
free -h
硬盘
df -h 说明: Disk free 空余硬盘
du -sh Disk usage 硬盘使用率
网络:
ifconfig
内核模块
驱动模块
etcetera 等等
twm = twm = Tom‘s Window Manager
2.Python物理机和Python关系
1.物理机的情况
多线程指的是,在一个进程中开启多个线程
进程(process) 线程(thread)
多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享
Python的线程虽然是真正的线程,但解释器执行代码时,
有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁
所有线程共享进程的内存
可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。
多核CPU上,可以运行多个进程(数量与CPU核心数相同),充分利用多核CPU
Python语言,单线程的异步编程模型称为协程
2.CPU密集型 vs IO密集型
CPU密集代码的执行中,多线程性能不如多进程
多线程对IO密集型代码比较友好
CPU密集型代码(各种循环处理、计数等等),推荐 多进程 - process
I/O密集型代码(文件处理、网络爬虫等), 推荐 多线程 - thread
3.情况
Queue Queue的作用是用来传递任务和接收结果
对于多进程,GIL就无法限制,多个进程可以再多个CPU上运行,充分利用多核优势
额外:
协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine
协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
yield(生成器)可以很容易的实现上述的功能,从一个函数切换到另外一个函数
异步编程asyncio库: python中使用协程最常用的库就是asyncio
3.Python3 通过标准库
本质: 切换+保存状态
进程+线程+协程
1.线程和进程
threading 和 multiprocessing
01.线程
_thread 和 threading 提供对线程的支持
其中 threading.currentThread()
在python中有GIL,线程锁,保证只有一个线程在计算,在不停的切换
python的线程属于内核级别的,即由操作系统控制调度
02.进程
需要mutliprocessing 因为每个核有单独的逻辑空间,互相不影响
每个进程都有自己独立的GIL
2.线程池和进程池
ThreadPoolExecutor 异步调用的 线程池 的Executor
ProcessPoolExecutor 异步调用的 进程池 的Executor
01.线程池:
ThreadPoolExecutor线程池
02.进程池:
ProcessPoolExecutor 进程池,与 multiprocessing 标准的多进程模块。
其实ProcessPoolExecutor也是对multiprocessing的封装调用,而multiprocessing则更加底层
Queue用于建立和操作队列,常和threading类一起用来建立一个简单的线程队列
Executor 对象 (map submit shutdown)
ThreadPoolExecutor 是 Executor 的子类,它使用线程池来异步执行调用
ThreadPoolExecutor.map
ThreadPoolExecutor.submit
ProcessPoolExecutor 类是 Executor 的子类,它使用进程池来异步地执行调用。
ProcessPoolExecutor 会使用 multiprocessing 模块,这允许它绕过 全局解释器锁 但也意味着只可以处理和返回可封存的对象
map返回一个迭代器,其中的回调函数的参数 最好是可以迭代的数据类型,
如list;如果有 多个参数 则 多个参数的 数据长度相同;
如: pool.map(work,[[1,2],[3,4]],[0,1]]) 中 [1,2]对应0 ;[3,4]对应1 ;
其实内部执行的函数为 work([1,2],0) ; work([3,4],1)
map返回的结果是有序结果;是根据迭代函数执行顺序返回的结果
使用map的优点是 每次调用回调函数的结果不用手动的放入结果list中
pool.submit()
submit方法提交可回调的函数,并返回一个future实例;
future对象包含相关属性((cancel cancelled done running exception))
例如: Future对象有一个done()方法,判断该Future是否己完成
方法 执行数据的结果是无序的
Future 类将可调用对象封装为异步执行。
Future 实例由 Executor.submit() 创建
Linux
ps aux
top
pstree -aup display a tree of processes
对应的进程ID就可以查看到该进程打开的线程数
service job Process thread
4.Python执行系统命令-子进程
os
os.system(cmd)的返回值是脚本的退出状态码,只会有0(成功),1,同时执行后结果直接打印在控制台,无法读取保存到文件&变量
os.popen(cmd)返回脚本执行的输出内容作为返回值。执行后不会打印到控制台,可通过read()读取结果
subprocess
os.system可以用 subprocess.call来替代,
os.popen可以使用subprocess.Popen来替代
带参数
# R语言
apply(X, MARGIN, FUN, ...) FUN: 自定义的调用函数
b