【python】进阶--->并发编程之进程

2023-12-20 14:36:48

在介绍进程之前,我先给大家介绍一些有用的概念

一、并发编程

多任务:操作系统同时运行多个任务
并行并发 :
并行 : 指任务数小于等于cpu核数,同一时刻,有多条指令在多个处理器上同时执行
并发 : 指任务数量大于cpu核数,同一时刻只有一条指令执行,但是多个指令被快速的轮换执行,使得具有多个任务同时执行的效果.

二、进程

编写完毕的代码,在没有运行的时候,称之为程序.正在运行的代码,就成为了进程.
操作系统是通过进程去完成一个一个的任务,进程是管理事务的基本单元,也是操作系统分配资源的基本单元.
进程拥有自己的独立环境(当前需要用到那些环境变量,程序运行的目录,当前是哪个用户在运行此程序等)和系统资源(处理器占用率,存储器,数据等等)

1、进程的生命周期

在这里插入图片描述

2、进程调度

要想多个进程交替运行,操作系统必须对这些进程进行调度,这个调度不是随机进行的,而是遵循一定的法则:进程的调度算法

  • 先来先服务调度算法
  • 短作业优先调度算法
  • 时间片轮转法
  • 多级反馈队列
    在这里插入图片描述
# 就绪状态,等待操作系统调度开始运行
import time  # 运行
print('程序开始运行')  # 运行
name = input('请输入:')  # 阻塞
# 就绪状态
print(name)  # 运行
time.sleep(1)  # 阻塞
# 就绪状态
print('程序结束运行')  # 运行
# 结束

就绪:当进程已经分配到除了cpu之外的所有必要的资源,只要获得cpu的调用即可立即执行.
执行:当程序已经获取cpu,正在cpu上运行
阻塞:由于等待某个事件发生而无法执行,便放弃cpu处于阻塞状态.引进阻塞的事件:等待i/o操作,申请的缓冲区不能满足,等待信号等等.

3、主进程和子进程

在并发编程中,当一个程序启动后,产生的进程就是主进程,之后新建的进程称为子进程

Process(group, target, name, args, kwargs)
group : 指定进程序组,不需要
target : 子进程需要执行的代码,传递函数的名字
name : 给进程设定一个名字,可以不设定.
默认为Process-N(N为从1开始递增的整数)
args : 给target指定的函数传递的参数,以元组的形式
kwargs : 给target指定的函数传递的参数,以字典的形式

4、Process创建的对象常用方法:

start() : 启动子进程
is_alive() : 判断进程子进程是否还活着
join(timeout) : 是否等待子进程执行结束,或者等待多少秒.
terminate() : 不论任务是否完成,立即终止子进程

from multiprocessing import Process
import time
import os
 
 
def test1():
    while True:
        print('test1-----')
        time.sleep(1)
 
 
def test2():
    while True:
        print('test2-----')
        time.sleep(1)
 
# 进程的创建1
# if __name__ == '__main__':
#     # 主进程
#     print('主进程开始')
#     p1 = Process(target=test1)
#     p2 = Process(target=test2)
#     print(p1.name)
#     print(p2.name)
#     # 启动进程
#     p1.start()
#     p2.start()
 
 
# 进程的创建2
class ProcessClass(Process):
    def __init__(self):
        super().__init__()
 
    def run(self):
        # os.getpid():获取当前进程pid
        # os.getppid():获取当前进程父进程pid
        t_start = time.time()
        print('子进程(%s)开始执行,父进程(%s)' %
              (os.getpid(), os.getppid()))
        time.sleep(2)
        t_end = time.time()
        print('(%s)执行结束,耗时%0.2f秒' % (os.getpid(), t_end-t_start))
 
 
if __name__ == '__main__':
    t_start = time.time()
    print('当前进程(%s)' % os.getpid())  # 主进程
    p1 = ProcessClass()
    p1.start()
    # 对于不包含target属性的Processs类的对象执行start方法,
    # 就会运行这个类中的run方法
    p1.join()  # 阻塞直到p1进程执行完毕再结束阻塞
    t_stop = time.time()
    print('(%s)执行结束,耗时%0.2f' % (os.getpid(), t_stop-t_start))

5、进程间不同享全局变量

在这里插入图片描述

from multiprocessing import Process
# def test(*args, **kwargs):
#     print(args, kwargs)
#
#
# if __name__ == '__main__':
#     p = Process(target=test, args=(1, ), kwargs={'name': 'wuluo'})
#     p.start()
 
 
list1 = [1, 2, 3, 4]
 
def test1():
    list1.append(5)
    print('test1---', list1)
 
def test2():
    print('test2---', list1)
 
if __name__ == '__main__':
    p1 = Process(target=test1)
    p1.start()
    p1.join()
    p2 = Process(target=test2)
    p2.start()

6、进程间的通信Queue()

进程是一个独立的资源分配单元,不同进程之间的资源是独立的,不能在一个进程中直接访问另一个进程的资源.但是不同的进程之间需要进行信息的交互和状态的传递等等,因此,需要进程间的通信.
Queue() : 括号内部没有指定最大可接受的消息数量,或者数字为负数,那么代表可接受的消息数量没有上限(内存的尽头)
Queue.put(item,block, timeout) : 将item写入消息队列.block默认为True
?如果block使用默认值True,且没有设置timeout秒.消息队列如果没有空间可写入,将被阻塞,直到队列腾出空间为止.
?如果设置了timeout秒,则会等待timeout秒,若还没有空间,则抛出queue.full异常.
?如果block设置为False,消息队列没有空间可写入,则会立即抛出queue.full异常.

import multiprocessing
 
q = multiprocessing.Queue(3)  # 括号内表示最多接收的消息数
q.put('消息1')
q.put('消息2')
q.put('消息3')
q.put('消息4', block=False)  # 当队列满了之后,会阻塞,不能写入

关于Python进程的介绍今天就到这里啦,后续我会为大家介绍线程以及协程的相关知识哦~
关注我,带你领略Python的风采~😍😍😍

文章来源:https://blog.csdn.net/m0_75141643/article/details/135035993
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。