并发编程 Process 互斥锁

时间:2021-07-20
本文章向大家介绍并发编程 Process 互斥锁 ,主要包括并发编程 Process 互斥锁 使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

进程理论

程序与进程的区别

'''
程序不是存在硬盘上的代码,相对来说是静态的
进程表示程序在执行的过程,是动态的
'''

进程的调度

  • 先来先服务调度算法

    '''对长作业有利,对短作业无益'''
    
  • 短作业优先调度算法

    '''对短作业有利,长作业无益'''
    

两对重要的概念

  • 同步和异步

    '''描述的是任务的提交方式'''
    同步:任务提交之后,原地等待任务的返回结果,等待过程中不做任何事情程序表面上表现出来的感觉就是卡住了
    异步:任务提交之后,不原地等待任务返回的结果,直接去做其他事情
    		事后,任务的返回结果会有一个任务回调机制自动处理
    
  • 阻塞和非阻塞

    '''描述的是程序的运行状态'''
    阻塞:阻塞态
    非阻塞:就绪态、运行态
    

上述概念的组合:最高效的一种组合就是异步非阻塞

开启进程的方式

from multiprocessing import Process
import time


def task(name):
    print('%s is running' % name)
    time.sleep(3)
    print('%s is over'%name)


if __name__ == '__main__':
  # 1、创建一个对象 target=>要执行的任务
    p = Process(target=task,args=('卡卡西里',))
    # 容器类型哪怕里面只有一个元素 建议要用逗号隔开
    # 2 开启进程
    p.start() # 告诉系统帮你创建一个进程 异步
    print('主进程')

总结

'''创建进程就是在内存中申请一块内存空间将需要运行的代码丢进去
一个进程对应在内存中就是一块独立的内存空间
多个进程对应在内存中就是多块独立的内存空间
进程与进程之间默认情况下是无法直接交互的,想要交互借助于第三方工具、模块
'''

join方法

jion 是让其他主进程等待子进程代码运行结束之后,再继续运行。不影响其他子进程的执行

from multiprocessing import Process
import time


def task(name):
    print('%s is running' % name)
    time.sleep(3)
    print('%s is over' % name)


if __name__ == '__main__':
    p1 = Process(target=task, args=('卡卡西里1',))
    p2 = Process(target=task, args=('卡卡西里2',))
    p3 = Process(target=task, args=('卡卡西里3',))
    start = time.time()
    p1.start()
    p2.start()
    p3.start()
    p1.join()
    p2.join()
    p3.join()
    print('主进程',time.time()-start)

 '''输出结果
卡卡西里2 is running
卡卡西里1 is running
卡卡西里3 is running
卡卡西里2 is over
卡卡西里1 is over
卡卡西里3 is over
主进程 3.0681638717651367
 '''
# for 循环 开启进程 join
from multiprocessing import Process
import time


def task(name, n):
    print('%s is running' % name)
    time.sleep(n)
    print('%s is over' % name)


if __name__ == '__main__':
    p_list = []
    start = time.time()
    for i in range(1,4):
        p = Process(target=task, args=('进程%s' % i, i))
        p.start()
        p_list.append(p)
    for p in p_list:
        p.join()
    print('主进程', time.time() - start)

Process参数

Process的父类里面的属性要传以下参数

'''group=None, target=None, name=None, args=(), kwargs={},
                 *, daemon=None'''
# target表示的是需要执行的任务,或函数
# name表示的是进程的名字 不传入的话,默认名字是Process-1 后面依次递增
# 也可以传值进行修改
p1 = Process(target=task,name='kakaxili_1' args=('卡卡西里1',))
# args 传入的是元组,传的是任务函数需要的参数 按位置传入
# kwargs 闯入的是字典,传的是任务函数需要的参数,关键字传入

Process类方法

p.start()  开启进程
p.join()   jion 是让其他主进程等待子进程代码运行结束之后,再继续运行。不影响其他子进程的执行
p.run()   没有开启子进程,而是把它当作一个进程执行了,相当于串行了
p.termainate() 终止该进程,但是需要时间
p.is_alive() 判断进程是否存活,存活返回True,否则返回False

Process属性

p.pid  p进程的id 在主进程中查看的
p.name p进程的进程名称
p.daemon = True  daemon默认传入的是False 设为True设置守护进程,主进程如果运行结束,子进程也跟着结束,但是必须放在start之前

获取进程ID的方法

import os

def func():
  print(os.getpid()) # 获取当前进程的id
  print(os.getppid())  # 获取父进程的id

互斥锁

在python的多线程和多进程中,当我们需要对多线程或多进程的共享资源或对象进行修改操作时,往往会出现因cpu随机调度而导致结果和我们预期不一致的问题,这时就需要对线程或者进程加锁,以保证一个线程或进程在对共享对象进行修改时,其他的线程或进程无法访问这个对象,直至获取锁的线程的操作执行完毕后释放锁。所以,锁在多线程和多进程中起到一个同步的作用,以保护每个线程和进程必要操作的完整执行。

import multiprocessing
import os
import time
from multiprocessing import Process, Lock


def task(i, lock):
    lock.acquire()  # 获得锁
    print('%s号进程,ID:%s 开始执行' % (i, os.getpid()))
    time.sleep(2)
    print('%s号进程,ID:%s 执行结束' % (i, os.getpid()))
    lock.release()  # 释放锁


if __name__ == '__main__':
    # 实例化得到一把锁
    multiprocessing.set_start_method('fork') # mac 解决办法
    lock = Lock()
    for i in range(1, 5):
        p = Process(target=task, args=(i, lock))
        p.start()
学习Python3 互斥锁遇到的mac系统遇到的错误 FileNotFoundError: [Errno 2] No such file or directory


mac系统
python3.4更新后,默认用“spawn”,开启进程,我们要主动指定为“fork”
spawn:使用此方式启动的进程,只会执行和 target 参数或者 run() 方法相关的代码。Windows 平台只能使用此方法,事实上该平台默认使用的也是该启动方式。相比其他两种方式,此方式启动进程的效率最低。
fork:使用此方式启动的进程,基本等同于主进程(即主进程拥有的资源,该子进程全都有)。因此,该子进程会从创建位置起,和主进程一样执行程序中的代码。注意,此启动方式仅适用于 UNIX 平台,os.fork() 创建的进程就是采用此方式启动的。
forserver:使用此方式,程序将会启动一个服务器进程。即当程序每次请求启动新进程时,父进程都会连接到该服务器进程,请求由服务器进程来创建新进程。通过这种方式启动的进程不需要从父进程继承资源。注意,此启动方式只在 UNIX 平台上有效。

在实例化锁之前添加
multiprocessing.set_start_method('fork')

原文地址:https://www.cnblogs.com/wuzhixian/p/15036413.html