Python

Python 多进程并发网络编程

2018-08-18  本文已影响0人  用1心

2018-08-18


psbZIOJOYAH.jpg

进程(Process):
  计算机中正在进行的应用程序叫做进程。一个进程包含了该应用程序的所有信息,如加载数据内存空间、代码、程序数据、对象句柄、执行单元等等。
  计算机中多线程的操作已经实现了多任务的处理机制了,但是多核CPU下的多进程并发编程的实现,能比多线程并发机制更加有效的利用和发挥硬件优势。

Python中的multiprocessing模块,可以实现多进程并发编程。
import multiprocessing #模块中常见的属性和方法

名称        作用
.Process    # 进程类型用于创建、管理一个进程
.Lock/Rloak    # 进程互斥锁/重用锁,用于进程同步
.Event    # 进程事件类型,用于进程同步
.Condition    # 进程条件类型,用于进程同步
.Queue    # 进程队列类型,用于多进程数据共享
.Manager    # 进程管理类型,多进程数据共享
.Listener|Client    # 进程监听|客户端,基于网络多进程之间的数据共享

1、多进程的基本操作
 1.1 创建一个面向过程的函数式进程

import multiprocessing, time, os

def hello_world():
  # 输出信息, 展示当前进程编号,  父进程编号     
   print("hello myname is process", os.getpid(),os.getppid()) 
 
if __name__ == "__main__":      
   proc = multiprocessing.Process(target=hello_process)  # 创建一个进程     

   proc.start()     #启动进程
  
     print("hello, i ma main:", os.getpid(), os.getppid()) 

运行程序,查看运行结果,通过进程编号就能看到主进程和创建的进程之间的关系:

hello , i  am main : 2456 2772 
hello my name is process 13536 2456 

从运行结果就能发现,main 方法运行的是主进程,通过multiprocessing 创建的子进程是由主进程产生的!
其中 2772 是 pycharm 工具进程创建的程序主进程
->2456 当前程序进程
->13536 子进程

1.2 面向对象的面向对象编程-_-||
  多进程的面向对象,的实现方式,类似多线程的操作模式
  自定义进程类型:继承系统进程标准类型multiprocessing.Process
  重写父类的run()方法,在方法中定义执行代码,run方法不用调用,会自动执行!!
  在使用时创建自定义进程类型的对象,调用对象的start()方法启动一个新的进程

import multiprocessing, os

class My_process(multiprocessing.Process):
  '''自定义一个进程类型'''
  def run(self):      # 重写run方法
    print("hello, my name id process", os.getpid(), os.getppid())

if __name__ == "__main__":
  print("hello, my name is main", os.,getpid(), os.getppid())
  # 创建一个进程
  my_proc = Myprocess()
  #启动一个进程
  my_proc.start()

执行结果,和函数式编程的结果相同:

hello, my name is main: 7048 2772
hello, my name is process: 3140 7048 
  1. 多进程模式下的数据操作
      (多线程的操作模式下,全局变量十多个线程共享的。所以多线程并发模式下对于数据的修改非常危险!)
      多进程模式下,全局变量的参数是不共享的。在执行代码时,全局变量的值会被进程复制到进程自己的代码块里执行,全局变量的参数是不会变的!!
    代码见下方:
import multiprocessing, time

# 定义全局变量
bl = 3

# 定义进程函数
def change_num():
    global bl
    while bl > 0:
        bl -= 1
        print(multiprocessing.Process().name, '进程里的全局变量:', bl)

if __name__ == "__main__":
    # 创建两个进程,并修改数据
    for i in range(2):
        p = multiprocessing.Process(target = change_num)
        p.start()

    time.sleep(2)
    print("这是全局变量", bl)

运行结果如下:

Process-1:1 进程里的全局变量: 2
Process-1:2 进程里的全局变量: 1
Process-1:3 进程里的全局变量: 0
Process-2:1 进程里的全局变量: 2
Process-2:2 进程里的全局变量: 1
Process-2:3 进程里的全局变量: 0
这是全局变量 3

可以发现进程里的全局变量的值虽然发生了变化,
但是外部全局变量的值没有改变!!

  1. 多进程的简化:内置进程池
       通过进程池Pool,可以快速创建多个进程执行指定函数,完成馅饼发处理操作

Pool的属性和方法:

名称           作用
apply(func, args)   #args-要传递参数, func-要执行的函数名称,同时阻塞当前进程知道该函数执行完成。
             函数func只会在进程池中的一个进程池运行
---------------------------------------------------
#该方法不会形成阻塞
apply_async(func, args, callback, error_callback)
func         (args-要传递参数, func-要执行的函数名称
args         函数执行完成之后可以通过结果对象的 get()方法获取结果 )
callback        #如果结果对象可用时会自动调用 callback 指定的函数
error_callback     #如果结果对象调用失败时会自动调用 error_callback 指定的函数
---------------------------------------------------
.close()   #Pool 进程池的底层工作机制是向进程池提交任务产生工作进程执行 
        该方法是主动停止给进程池提交任务,并等待所有提交任务执行完成退出 
.terminate()   #立即结束该进程,当进程池对象被回收时自动调用该方法 
.join()     # 等待工作进程退出,再次之间必须调用 close()或者 teminate 

实例如下:

import multiprocessing, time, os

def my_proc():
    print(multiprocessing.current_process().name, "一个进程正在工作", os.getppid(), os.getpid())
    time.sleep(1)


if __name__ == "__main__":
    # 创建一个进程池
    pool = multiprocessing.Pool(2)

    # 循环任务
    for i in range(20):
        pool.apply_async(my_proc)

    # 停止提交任务
    pool.close()
    # 独占执行
    pool.join()

结果如下:

SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-1 一个进程正在工作 11596 14100
SpawnPoolWorker-2 一个进程正在工作 11596 13680
SpawnPoolWorker-1 一个进程正在工作 11596 14100

Process finished with exit code 0

可以发现进程池里的两个进程处理了循环的8个任务

  1. 多个进程通信,即数据实现共享(待实际操作)
      Python中提供了multiprocessing.Manager类型,该类型内置了大量的用于实现数据共享的操作

常见的属性和方法:

名称           描述
Array          内置进程间共享 数组 类型
Queue          内置进程间共享 队列 类型
list()          内置进程间共享 列表 类型
dict()          内置进程间共享 字典 类型
value          内置进程间共享 值 类型

上一篇下一篇

猜你喜欢

热点阅读