返回顶部
首页 > 资讯 > 后端开发 > Python >Python学习—pyhton中的进程
  • 375
分享到

Python学习—pyhton中的进程

进程Pythonpyhton 2023-01-31 07:01:32 375人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

1.进程定义 进程: 进程就是一个程序在一个数据集上的一次动态执行过程。进程一般由程序、数据、进程控制块(pcb)三部分组成。(1)我们编写的程序用来描述进程要完成哪些功能以及如何完成;(2)数据则是程序在执行过程中所需要使用的资源;(3)

1.进程定义

进程: 进程就是一个程序在一个数据集上的一次动态执行过程。进程一般由程序、数据、进程控制块(pcb)三部分组成。
(1)我们编写的程序用来描述进程要完成哪些功能以及如何完成;
(2)数据则是程序在执行过程中所需要使用的资源;
(3)进程控制块用来记录进程的所有信息。系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志。

2.创建进程

新创建的进程在内存独立开辟一块空间,不与其他进程共享空间、数据。
同一个进程中,新创建的线程与此进程里其他线程共享空间、数据。

1.os.fork()函数

os模块的三个方法:
os.fork()创建一个当前进程的子进程
os.getpid()获取当前进程pid
os.getppid()获取当前进程的父进程的Pid
关于fork():
它用来创建一个进程,即为当前进程的子进程,复制父进程的所有代码并从fork语句处开始运行。运行父进程还是子进程的取决于当前os调度策略。
在父进程中返回子进程的pid,在子进程中返回0。即返回0表示在子进程中运行,返回大与0的数表示在父进程中运行。

例子:

import os

print('当前进程:',os.getpid())
print('当前进程的父进程:',os.getppid())

pid = os.fork()
if pid == 0:
    print('此时为子进程:',os.getpid(),'\n其父进程:',os.getppid())
else:
    print('父进程:',os.getpid(),'\nos.fork的返回值pid:',pid)

运行结果:

当前进程: 16839
当前进程的父进程: 2912
父进程: 16839 
os.fork的返回值pid: 16842
此时为子进程: 16842 
其父进程: 16839

从运行结果中看,在linux中fork产生子进程后是先运行父进程,当父进程结束后再进入子进程运行。

2.实例化进程类

直接通过实例化进程类multiprocessing.Process创建新进程。
和线程类一样,进程类也有start()方法,join()方法。调用对象的start()方法实例上也是调用的类中的run()方法。

# 导入进程模块
import multiprocessing
import os

def job(ss):
    print(ss,'当前子进程:%s' %os.getpid())

#实例化进程类,并提交任务,传入任务所需要的参数
p1 = multiprocessing.Process(target=job,args=('abc',))
p1.start()
p2 = multiprocessing.Process(target=job,args=('123',))
p2.start()

# 和线程一样,进程也有join方法。
p1.join()
p2.join()

print('完成......')

运行结果:

abc 当前子进程:17234
123 当前子进程:17235
完成......

3.继承进程类来自定义进程类

继承python提供的进程类,重写方法,创建自己所需要的进程类,再实例化自定义的进程类。

import multiprocessing

class Job(multiprocessing.Process):
    #重写构造方法
    def __init__(self,cc):
        super(Job, self).__init__()
        self.cc = cc

    #重写run方法,和线程一样
    def run(self):
        print(self.cc)

#实例化对象
if __name__ == "__main__":
    pp = []
    for i in range(10):
        p = Job(str(i)+':123456')
        pp.append(p)
        p.start()

    for p in pp:
        p.join()
    print('hahhahaha')

运行结果:

0:123456
1:123456
2:123456
3:123456
4:123456
5:123456
6:123456
7:123456
8:123456
9:123456
hahhahaha

3.多进程与多线程的对比

import threading
import multiprocessing
from timeit import timeit

class Jobthread(threading.Thread):
    def __init__(self,li):
        super(Jobthread,self).__init__()
        self.li = li
    def run(self):
        sum(self.li)

class Jobprocess(multiprocessing.Process):
    def __init__(self,li):
        super(Jobprocess, self).__init__()
        self.li = li
    def run(self):
        for i in self.li:
            sum(i)

# 这个装饰器是自己写的,用来计算某个函数执行时间
@timeit
def use_Pro(list):
    for i in range(0,len(list), 1000):
        p = Jobprocess(list[i:i+1000])
        p.start()

@timeit
def use_Thr(list):
    for li in list:
        t = Jobthread(li)
        t.start

if __name__ == "__main__":
    list = [[1,2,3,4,5,6],[2,3,4,5,6,7],[3,4,5,6,7,8],[4,5,6,7,8,9]]*1000
    use_Pro(list)
    use_Thr(list)

运行结果:

use_Pro运行时间0.0041866302490234375
use_Thr运行时间0.02240157127380371

正如看到的结果一样,多进程适合计算密集型任务,多线程适合i/o密集型任务。

3.守护进程与终止进程

1.守护进程-daemon属性

和线程类似,进程类也有一个daemon属性,默认值为False。
当改变他的值为True时,当主进程结束,就会强行终止其他的所以进程。
实例:
(1)第一个程序

import multiprocessing
import time

def job():
    print('开始子进程')
    time.sleep(3)
    print('子进程结束')

if __name__ == "__main__":
    p = multiprocessing.Process(target=job)
    p.start()
    print("程序结束......")

运行结果:

程序结束......
开始子进程
子进程结束

主进程结束,其他进程还在继续执行。
(2)第二个程序

import multiprocessing
import time

def job():
    print('开始子进程')
    time.sleep(3)
    print('子进程结束')

if __name__ == "__main__":
    p = multiprocessing.Process(target=job)
    p.daemon = True
    p.start()
    print("程序结束......")

运行结果:

程序结束......

当主进程结束,其他进程将会被强制终止结束。

2.终止进程

import multiprocessing
import time

def job():
    print('开始子进程')
    time.sleep(3)
    print('子进程结束')

if __name__ == "__main__":
    p = multiprocessing.Process(target=job)
    p.daemon = True
    print(p.is_alive())     #启动进程之前查看进程状态
    p.start()
    print(p.is_alive())     #启动进程之后查看进程状态
    p.terminate()           #终止进程
    print(p.is_alive())     #终止进程命令一发出后,查看进程状态。此时进程在释放过程中,还没有被完全释放。
    p.join()                #先让进程完全释放
    print(p.is_alive())     #最后查看进程状态

    print("程序结束......")

运行结果:

False
True
True
False
程序结束......

4.进程间通信

"""
通过队列实现进程间通信,队列充当消息管道的作用(类似生产者消费者模型)
这里通信一直存在,也就是这两个进程会一直存在,没有销毁释放。
"""
import multiprocessing
from multiprocessing import Queue
import time

class Put_news(multiprocessing.Process):
    def __init__(self,queue):
        super(Put_news, self).__init__()
        self.queue = queue
    def run(self):
        for i in range(100):
            self.queue.put(i)
            print("传递消息:%s" %i)
            time.sleep(0.1)

class Get_news(multiprocessing.Process):
    def __init__(self,queue):
        super(Get_news, self).__init__()
        self.queue = queue
    def run(self):
        while True:
            time.sleep(0.11)
            print("接收消息++++++++++++:%s" %(self.queue.get()))

if __name__ == "__main__":
    q = Queue()
    p = Put_news(q)
    g = Get_news(q)
    p.start()
    g.start()

    if not p.is_alive():
        g.terminate()

运行结果:
Python学习—pyhton中的进程

Python学习—pyhton中的进程

5.分布式进程

任务需要处理的数据特别大, 希望多台主机共同处理任务。multiprocessing.managers子模块里面可以实现将进程分布到多台机器上
(管理端主机要运算一些列任务,通过与其他主机建立“连接“,将任务分配给其他主机执行,并将执行结果返回给管理端主机。)
管理端主机代码:

import random
from queue import Queue
from multiprocessing.managers import BaseManager

# 1.创建队列(发送任务的队列,收取结果的队列)
task_queue = Queue()
result_queue = Queue()

# 第二三步骤可以互换顺序
# 2.将队列注册到网络(这样其他主机可以通过网络接收任务,发送结果)
# 注册的队列(任务队列,结果队列)的唯一标识码分别为'put_task_queue','get_result_queue'
BaseManager.reGISter('put_task_queue',callable=lambda :task_queue)
BaseManager.register('get_result_queue',callable=lambda : result_queue)

# 3.绑定端口(3333),设定密码(hahahaha)
manager = BaseManager(address=('172.25.254.158',3333),authkey=b'hahahaha')

# 4.启动manager,开始共享队列
manager.start()

# 5.通过网络访问共享的队列
task = manager.put_task_queue()
result = manager.get_result_queue()

# 6.向任务队列中放入执行任务的数据,这里放入100个任务
for i in range(100):
    n = random.randint(10,500)
    task.put(n)
    print('任务列表加入数据:'+str(n))

# 7.从结果队列中读取各个主机的任务执行结果
for j in range(100):
    res = result.get()
    print('执行结果:'+str(res))

# 8.任务执行结束,关闭共享队列
manager.shutdown()

运算主机代码:

"""
在各个工作主机上执行的代码相同
"""

from multiprocessing.managers import BaseManager

# 1. 连接manager端,获取共享的队列
import time

worker = BaseManager(address=('172.25.254.158',3333),authkey=b'hahahaha')

# 2.注册队列,去获取网络上共享的队列中的内容
BaseManager.register('put_task_queue')
BaseManager.register('get_result_queue')

# 3.连接网络
worker.connect()

# 4.通过网络访问共享的队列

task = worker.put_task_queue()
result = worker.get_result_queue()

# 5.读取任务,处理任务,这里读取了50个任务进行处理
# 每台运算主机上的处理任务数量可以不同,不过为了避免修改代码,一般都相同。
for i in range(50):
    n = task.get()
    print('执行任务 %d**2 = '%(n))
    res = '%d**2=%d' %(n,n**2)  #这里设置执行的任务是求平方
    result.put(res)     #将结果放入结果队列
    time.sleep(1)       #休息1秒

print('工作主机执行任务结束.....')

6.进程池

和线程一样,进程也有进程池。
1.第一种方法

import multiprocessing
import time

def job(id):
    print('start id ---> %d' %id)
    print('end id ----> %d' %id)
    time.sleep(3)
# 创建含有8个进程的进程池
pool = multiprocessing.Pool(8)
# 给进城池的进程分配任务
for i in range(12):
    pool.apply_async(job,args=(i,))

# 关闭进程池,使进程池不再工作运行
pool.close()
# 等待所有子进程结束之后再开始主进程
pool.join()

print('all works completed!')

运行结果:

start id ---> 0
end id ----> 0
start id ---> 1
end id ----> 1
start id ---> 2
end id ----> 2
start id ---> 3
end id ----> 3
start id ---> 4
end id ----> 4
start id ---> 5
end id ----> 5
start id ---> 6
end id ----> 6
start id ---> 7
end id ----> 7
start id ---> 8
end id ----> 8
start id ---> 9
end id ----> 9
start id ---> 10
end id ----> 10
start id ---> 11
end id ----> 11
all works completed!

2.第二种方法

from concurrent.futures import ProcessPoolExecutor
import time
def job(id):
    print('start id ---> %d' %id)
    print('end id ----> %d' %id)
    time.sleep(3)

# 创建含有2个进程的进程池
pool = ProcessPoolExecutor(max_workers=2)
# 给进程池的进程分配任务,submit方法返回一个_base.Future对象
f1 = pool.submit(job,1)
f2 = pool.submit(job,2)
f3 = pool.submit(job,3)
f4 = pool.submit(job,4)
# 执行f1对象的各种方法
f1.done()
f1.result()

运行结果:

start id ---> 1
end id ----> 1
start id ---> 2
end id ----> 2
start id ---> 3
end id ----> 3
start id ---> 4
end id ----> 4

3.第三种方法

from concurrent.futures import ProcessPoolExecutor
import time
def job(id):
    print('start id ---> %d' %id)
    print('end id ----> %d' %id)
    time.sleep(1)
pool = ProcessPoolExecutor(max_workers=3)
pool.map(job,range(1,10))

运行结果:

start id ---> 1
end id ----> 1
start id ---> 2
end id ----> 2
start id ---> 3
end id ----> 3
start id ---> 4
end id ----> 4
start id ---> 5
end id ----> 5
start id ---> 6
end id ----> 6
start id ---> 7
end id ----> 7
start id ---> 8
end id ----> 8
start id ---> 9
end id ----> 9

--结束END--

本文标题: Python学习—pyhton中的进程

本文链接: https://lsjlt.com/news/191366.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python学习—pyhton中的进程
    1.进程定义 进程: 进程就是一个程序在一个数据集上的一次动态执行过程。进程一般由程序、数据、进程控制块(pcb)三部分组成。(1)我们编写的程序用来描述进程要完成哪些功能以及如何完成;(2)数据则是程序在执行过程中所需要使用的资源;(3)...
    99+
    2023-01-31
    进程 Python pyhton
  • Python进程学习
    线程及进程概念可自行学习 Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后...
    99+
    2023-01-31
    进程 Python
  • Python 学习笔记 - 多进程和进程
    前面学习了多线程,接下来学习多进程的创建和使用。多进程更适合计算密集型的操作,他的语法和多线程非常相像,唯一需要注意的是,多线程之间是可以直接共享内存数据的;但是多进程默认每个进程是不能访问其他进程(程序)的内容。我们可以通过一些特殊的方式...
    99+
    2023-01-31
    进程 学习笔记 Python
  • python基础学习21----进程
    python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。 进程与线程的使用有很多相似之处,有关线程方面的知识请参考https://www.cnblogs.com/sfen...
    99+
    2023-01-30
    进程 基础 python
  • Python学习—python中的线程
    1.线程定义 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。一个进程至少有一个线程,一个进程必定有一个...
    99+
    2023-01-31
    线程 Python python
  • 浅谈pyhton学习中出现的各种问题(新手必看)
    目前比较杂乱无章,后续还会有一些添加补充 1、标识符 (1)标识符是区分大小写的。 (2)标示符以字母或下划线开头,可包括字母,下划线和数字。 (3)以下划线开头的标识符是有特殊意义的。 2、参数前加星号(...
    99+
    2022-06-04
    浅谈 必看 新手
  • Python学习之进程和并发
    从Python2.4 以后,subprocess模块负责衍生出新的进程,和标准输入,标准输出,标准错误输出交互,并监听返回值。Subprocess模块是用来取代一些老的模块,例如os.system, os.spawn, os.popen和p...
    99+
    2023-01-31
    进程 Python
  • Python学习记录-多进程和多线程
    [TOC] 1. 进程和线程 进程 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。广义定义:进程是一个具有一定独立功能的程序关于某...
    99+
    2023-01-31
    多线程 进程 Python
  • Python语法学习之进程池与进程锁详解
    目录进程池什么是进程池进程池的创建模块 - multiprocessing创建进程池函数 - Pool进程池的常用方法apply_async 函数演示案例close 函数与 join...
    99+
    2024-04-02
  • Python学习教程(Python学习路线):Python——SciPy精讲
    Python学习教程(Python学习路线):Python——SciPy精讲SciPy 是 Python 里处理科学计算 (scientific computing) 的包,使用它遇到问题可访问它的官网 (https://www.scipy...
    99+
    2023-06-02
  • Python语法学习之进程间的通信方式
    目录什么是进程的通信队列的创建 - multiprocessing进程之间通信的方法进程间的通信 - 队列演示案例批量给 send 函数加入数据小节进程间通信的其他方式 - 补充什么...
    99+
    2024-04-02
  • python进阶学习路线(全)
    学习路线: 1.硬件: 1、操作系统简介 2、第二篇:操作系统 2.linux基础: 1、初始Linux 2、基本使用  3、Linux进阶 3.python基础 : 1、python...
    99+
    2023-01-31
    进阶 路线 python
  • 循序渐进学习 Python loggin
    logging 库采用模块化的方式提供了几种类型的组件:loggers,handlers,filters,formatters。 Loggers 暴露了应用程序代码可以直接使用的接口Handlers 发送日志记录(由 loggers ...
    99+
    2023-01-31
    循序渐进 Python loggin
  • 怎么对Python程序学习过程进行总结
    今天就跟大家聊聊有关怎么对Python程序学习过程进行总结,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。你需要注意一些问题,比如代码编程和调试过程中的问题,这些一定要仔细和认真,Py...
    99+
    2023-06-17
  • python中asyncio异步编程学习
    1.   想学asyncio,得先了解协程 携程的意义: 计算型的操作,利用协程来回切换执行,没有任何意义,来回切换并保存状态 反倒会降低性能。 ...
    99+
    2024-04-02
  • Python中的Descriptor描述符学习教程
    Descriptor是什么?简而言之,Descriptor是用来定制访问类或实例的成员的一种协议。额。。好吧,一句话是说不清楚的。下面先介绍一下Python中成员变量的定义和使用。 我们知道,在Python...
    99+
    2022-06-04
    教程 Python Descriptor
  • 详解JUC并发编程中的进程与线程学习
    目录进程与线程进程线程同步异步串行并行执行时间创建和运行线程Thread 与 Runnable 的关系原理分析查看进程线程运行原理线程上下文切换start与run方法sleep方法s...
    99+
    2024-04-02
  • python多线程学习
    python多线程学习:python中的线程使用的两种方式:函数或者用类来包装线程对象。1、函数式:调用thread模块中start_new_thread()函数来产生新线程。#!/usr/bin/env python #coding:ut...
    99+
    2023-01-31
    多线程 python
  • python 线程池学习
    #!/usr/bin/pythonimport Queue, threading, sysfrom threading import Threadimport time,urllibclass Worker(Thread):   worke...
    99+
    2023-01-31
    线程 python
  • Python学习教程(附Python学习路线图):Pandas中第二好用的函数
    本次的Python学习教程是关于Python数据分析实战基础相关内容,本文主要讲的是Pandas中第二好用的函数——谦虚的apply。为什么说第二好用呢?那第一呢?秉承这谦虚使人进步,骄傲使人落后的品质,apply选择做一个谦虚又优雅的函数...
    99+
    2023-06-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作