简介

线程理解中介绍过,再回顾一遍,一个应用程序由多个进程组成,一个进程由多个线程组成,由操作系统根据优先级、时间片来绝对线程的运行

进程

python的进程不同于线程,在主流的cpython解释器下,无论创建多少线程,都只会在一个cpu上运行,与java等语言有所区别,进程则与其他语言类似,会占用对应的cpu资源,因此进程相对于线程来说开销会大一点,进程适用于计算密集型程序

常见的进程创建方式

1.multiprocessing的Process创建进程

from multiprocessing import Process
import time def run(name):
time.sleep(10)
print(f'process statrt:{name}') p = Process(target=run, args=('test1',), name='test1')
p.start()

2.subprocess创建进程

subprocess创建进程一般用于命令的执行,详细信息可见subprocess文章

stderr=subprocess.STDOUT:代表将错误输出也输出到stdout

import subprocess

command = "adb devices"
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print(p.stdout.readlines())

进程间通信

由于进程的内存空间是相对独立的,因此无法像线程使用全局变量的方式去进行进程间通信,需要借助一定的中间媒介,下面介绍几种进程间通信的方式。

1.Queue(队列)

此处不是queue中的队列,是mutiprocessing中的队列

from multiprocessing import Process, Queue

queue = Queue()
def put(msg):
queue.put(msg) def get():
msg = queue.get()
print(f"msg:{msg}") p = Process(target=put, args=("message",))
p.start()
p2 = Process(target=get)
p2.start()

2.Pipe

适用于两个进程间通信,recv、send, 与socket.socketpair()类似

管道:适用于两个线程之间的数据交互,感觉类似于socket通信

from multiprocessing import Process, Pipe

send_p, recv_p = Pipe()
def send(msg):
send_p.send(msg) def recv():
msg = recv_p.recv()
print(f"msg:{msg}") p = Process(target=send, args=('test',))
p.start()
p2 = Process(target=recv)
p2.start()

3.Manager

推荐使用这种方式,支持 list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array.

from multiprocessing import Process, Manager, Lock

manager = Manager()
# 字典类型
d = manager.dict({'count':0})
# 列表类型
l = manager.list([])
# 加锁,防止数据混乱
lock = Lock()
def start_process1(d, l:list):
lock.acquire()
d['count'] += 1
l.append(d['count'])
lock.release()
print(d['count'])
print(l) p_list = [] for i in range(10):
p = Process(target=start_process1, args=(d, l))
p.start()
p_list.append(p) for p in p_list:
p.join()

4.socket通信

支持跨进程、跨语言通信

例如:socket.socketpair()

from multiprocessing import Process
import socket socket1, socket2 = socket.socketpair()
def send(msg):
print(socket1)
print(socket2)
# 关闭不需要的socket
socket2.close()
socket1.send(msg.encode('utf8')) def recv():
print(socket1)
socket1.close()
print(socket2)
print(socket2.recv(1024)) p = Process(target=send, args=('test',))
p.start()
p2 = Process(target=recv)
p2.start()

5.中间介质:文件、事件中心等

此处不再赘述

进程池

1.使用multiprocessing中的Pool模块

from multiprocessing import Pool
import time def start_process(n):
print(f'{n} process start')
time.sleep(10)
print(f'{n} process finish')
return n def callback(n):
"""
回调参数为进程的return的返回值
"""
print(f"callback:n:{n}") def error_callback():
print(f"error_callback") pool = Pool(4)
for i in range(5):
# 异步执行
pool.apply_async(func=start_process, args=(str(i+1),),callback=callback)
pool.close()
pool.join()
for i in range(5):
# 同步执行
pool.apply(func=start_process, args=(str(i+1),))
pool.close()
pool.join()
# 批量对一个序列中的元素进行操作,同步
pool.map(func=start_process, iterable=[1,2,3,4])
pool.close()
pool.join()
# 批量对一个序列中的元素进行操作,异步
pool.map_async(func=start_process, iterable=[1,2,3,4], callback=callback)
pool.close()
pool.join()
print('process exec finish')

2.使用concurrent.futures下的ProcessPoolExecutor

默认如果不设置进程池的大小,则为cpu核心数或者1

ProcessPoolExecutor默认是异步的

使用submit

from concurrent.futures import ProcessPoolExecutor
import time def start_process(n, m):
print(f'{n} process start')
time.sleep(10)
print(f'{n} process finish')
return n, m pool = ProcessPoolExecutor(4)
ret_list = []
for i in range(5):
# 多个参数使用带参方式传入
ret = pool.submit(fn=start_process, n=str(i+1), m=str(i))
ret_list.append(ret)
for ret in ret_list:
print(ret.result())
# 等待进程全部结束再继续运行,相当于join
pool.shutdown(wait=True)

使用map,需要注意的是多参数传入时,最好使用args传入

def start_process_muti(n, m):
print(f'{n} process start')
time.sleep(10)
print(f'{n} process finish')
return n, m # 需要使用args接收多参数,防止出现缺少某一个位置参数的问题
def start_process_do(args):
return start_process_muti(*args) data = [(i,j) for i in range(5) for j in range(5)]
print(data)
ret = pool.map(start_process_do, data)
print(list(ret))

python 进程理解的更多相关文章

  1. python——进程、线程、协程

    Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env pytho ...

  2. python进程、多进程

    进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当 ...

  3. python 进程和线程(代码知识部分)

    二.代码知识部分 一 multiprocessing模块介绍: python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情 ...

  4. [ python ] 进程的操作

    目录 (见右侧目录栏导航)- 1. 前言- 2. multiprocess模块- 2.1 multiprocess.Process模块    - 2.2 使用Process模块创建进程    - 2. ...

  5. 用 C# 来守护 Python 进程

    背景 目前我主要负责的一个项目是一个 C/S 架构的客户端开发,前端主要是通过 WPF 相关技术来实现,后端是通过 Python 来实现,前后端的数据通信则是通过 MQ 的方式来进行处理.由于 Pyt ...

  6. python 进程和线程-线程和线程变量ThreadLocal

    线程 线程是由若干个进程组成的,所以一个进程至少包含一个线程:并且线程是操作系统直接支持的执行单元.多任务可以由多进程完成,也可由一个进程的多个线程来完成 Python的线程是真正的Posix Thr ...

  7. 第 10 章 python进程与多进程

    一.背景知识 顾明思义,进程即正在执行的一个过程,进程是对正在云的程序的一个抽象. 进程的概念起源与操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一,操作系统的其他所 ...

  8. python——进程基础

    我们现在都知道python的多线程是个坑了,那么多进程在这个时候就变得很必要了.多进程实现了多CPU的利用,效率简直棒棒哒~~~ 拥有一个多进程程序: #!/usr/bin/env python #- ...

  9. 使用gdb调试Python进程

    使用gdb调试Python进程 有时我们会想调试一个正在运行的Python进程,或者一个Python进程的coredump.例如现在遇到一个mod_wsgi的进程僵死了,不接受请求,想看看究竟是运行到 ...

随机推荐

  1. vue - Vue脚手架(终结篇)/ vue动画

    几天的内容不是很多,因为我们脚手架的学习告一段落了,也是为了跟明天开始的内容有一个区分. 明天将会有一个非常重要的内容来了,各位,vue中的ajax他来了,这个绝对是重量级,有点兴奋! 十一.TODO ...

  2. JuiceFS v1.0 beta3 发布,支持 etcd、Amazon MemoryDB、Redis Cluster

    JuiceFS v1.0 beta3 在元数据引擎方面继续增强,新增 etcd 支持小于 200 万文件的使用场景,相比 Redis 可以提供更好的可用性和安全性.同时支持了 Amazon Memor ...

  3. MySQL闪回工具之binlog2sql

    一.binlog2sql 1.1 安装binlog2sql git clone https://github.com/danfengcao/binlog2sql.git && cd b ...

  4. 使用MinIO搭建对象存储服务

    1.MinIO是什么? MinIO 是一款高性能.分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件.即X86等低成本机器也能够很好的运行MinIO. MinIO与传统的存储和其 ...

  5. 好客租房29-从jsx中抽离事件处理程序

    从jsx中抽离过多js逻辑代码 会显得非常混乱 推荐:将逻辑抽离到单独的方法中 保证jsx结构清晰 //导入react     import React from 'react'           ...

  6. 个人冲刺(五)——体温上报app(二阶段)

    冲刺任务:完成用户登录和随机验证码功能 loginActivity.java package com.example.helloworld; /** * 纯粹实现登录注册功能,其它功能都被注释掉了 * ...

  7. 每天一个 HTTP 状态码 102

    102 Processing 102 Processing 是用于 WebDAV协议 请求的状态码. 这个状态码表示服务器已经收到了客户端的请求,正在处理,但暂时还没有可接触的响应.可以用于防止客户端 ...

  8. 一个恢复CSI挂载信息的解决方法

    一个恢复CSI挂载信息的解决方法 问题描述 之前有做过一个华为OBS 的CSI插件,其基本运作原理如下图所示.CSI插件Pod挂载了主机的/var/lib/kubelet/pods目录,当创建挂载Pv ...

  9. Java有根儿:Class文件以及类加载器

    JVM 是Java的基石,Java从业者需要了解.然而相比JavaSE来讲,不了解JVM的一般来说也不会影响到工作,但是对于有调优需求或者系统架构师的岗位来说,JVM非常重要.JVM不是一个新的知识, ...

  10. 前端CSS3布局display:grid用法

    前端CSS3布局display:flex用法 1. 先附上代码 点击查看代码 <!DOCTYPE html> <html> <head> <meta char ...