Python并行编程(七):多进程的基本使用和与多线程的差别

进程

 因为GIL的存在,Python中的多线程其实并非真正的多线程,若是想要充分地使用多核CPU的资源,在Python中大部分状况须要使用多进程。Python提供了很是好用的多进程模块multiprocessing,只须要定义一个函数,Python会完成其余全部事情。借助这个模块,能够轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通讯和共享数据、执行不一样形式的同步,提供了ProcessLockQueuePipe等组件。python

  multiprocessing模块是Python中的多进程模块。与threading.Thread相似,它能够利用multiprocessing.Process对象来建立一个进程。该进程能够运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(),run(), join()的方法。此外multiprocessing模块中也有Lock/Event/Semaphore/Condition类 (这些对象能够像多线程那样,经过参数传递给各个进程),用以同步进程,其用法与threading模块中的同名类一致。因此,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。 固然多进程的定义方式也和多线程相似,即两种方式:多线程

目标函数实例化定义新的进程:

# 导入多进程模块
from multiprocessing import Process

# os.getpid() 获取当前进程的id
import os

def run_proc(name):
    print('{} child process is {}'.format(name, os.getpid()))

if __name__ == '__main__':
    print("Parent process is {}".format(os.getpid()))
    p = Process(target=run_proc, args=('test', ))
    print('child process will start...')
    p.start()
    p.join()

    print('child process end.')
复制代码

运行截图以下: 并发

运行截图

继承类来定义新的进程

from multiprocessing import Process
import os


class RunProc(Process):
    def __init__(self, name):
        Process.__init__(self)

        self.name = name

    def run(self):
        print('{} child process is {}'.format(self.name, os.getpid()))


if __name__ == "__main__":
    print("Parent process is {}".format(os.getpid()))
    p = RunProc('test')
    print('child process will start...')
    p.start()
    p.join()

    print('child process end.')
复制代码

运行结果以下: 函数

运行截图
咱们能够看见,多进程的使用方式和多线程几乎同样,好比如下: Process([group [, target [, name [, args [, kwargs]]]]])

  • group: 线程组,目前尚未实现,库引用中提示必须是None;
  • target: 要执行的方法;
  • name: 进程名;
  • args/kwargs: 要传入方法的参数。

实例方法:测试

  • is_alive():返回进程是否在运行。
  • join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。
  • start():进程准备就绪,等待CPU调度
  • run():strat()调用run方法,若是实例进程时未制定传入targetstart执行默认的· run()方法。
  • terminate():无论任务是否完成,当即中止工做进程

属性:spa

  • daemon:和线程的setDeamon功能同样
  • exitcode(进程在运行时为None、若是为–N,表示被信号N结束)
  • name:进程名字。
  • pid:进程号。

进程的独立性:

和线程不同的是,进程之间相互独立,咱们能够从全局变量的修改窥见一些:线程

from multiprocessing import Process

# 测试数据
ex_list = 'Hello World'

# 修改数据进程
def revise_data():
    global ex_list

    # 修改全局变量
    ex_list = ex_list + ' with write revise_data process.'
    print('wirte result:', ex_list)

# 查看数据进程
def view_data():
    print(ex_list)

if __name__ == "__main__":
    process_revise = Process(target=revise_data)
    process_view = Process(target=view_data)

    process_revise.start()

    # 主进程等待写入进程执行完成之后代码 再继续往下执行
    process_revise.join()

    process_view.start()
    process_view.join()

    print("process end.")
复制代码

运行截图以下: code

运行结果
咱们定义了两个进程,分别用来修改全局变量和查看修改后的数据,咱们看见虽然修改的进程已经成功修改了变量,可是在查看进程中全局变量仍然是原来的值,即进程之间是不共享全局变量的,即建立子进程实际上是对主进程进行拷贝,进程之间相互独立,访问的全局变量不是同一个,因此进程之间不共享全局变量。
相关文章
相关标签/搜索