【高并发编程】Python中多进程多线程

多进程

Python提供multiprocessing模块来实现多进程,可以跨平台版本,multiprocessing模块提供了Process 类来表示一个进程对象。

Linux/Unix操作系统提供了fork() 系统调用,来实现父子进程。子进程永远返回0,父进程返回子进程的ID。

多进程实现

多进程通过Queue、Pipes 等通信

start() 开始调用子进程

join()主进程等待子进程调用结束后,在继续往下运行,用于进程间的同步

import multiprocessing
import os

class subMp(multiprocessing.Process):
    """
    继承多进程multiprocessing模块中的Process类
    """
    def __init__(self, count):
        """
        构造函数
        """
        # 使用父类构造函数让父类实现初始化self
        multiprocessing.Process.__init__(self)
        self.count = count

    def run(self):
        """
        重写Process类中run方法,使用start()方法来调用此run方法
        """
        print ("子进程: %s" % os.getpid())
        print ("父进程: %s" % os.getppid())
        print ("count: %d" % self.count)

if __name__ == "__main__":
    # 创建进程池
    mp = []
    for i in range(5):
        mp.append(subMp(i))
    # 调用每个进程
    for m in mp:
        m.start()  #调用类中的run方法

运行结果:

子进程: 9440
父进程: 22420
count: 1
子进程: 17140
子进程: 19476
父进程: 22420
count: 3
父进程: 22420
count: 2
子进程: 15900
父进程: 22420
count: 0
子进程: 15888
父进程: 22420
count: 4

进程池Pool

apply_async()异步非阻塞执行,不用等子进程执行完毕,根据系统调用进行进程间切换。

#-*- coding: utf-8

from multiprocessing import Pool
import os


def func(i):
    print (i)
    print (os.getpid())


if __name__ == "__main__":
    """
    创建线程池
    """
    p = Pool(5)
    for i in range(5):
        # 异步非阻塞执行(被调用函数,函数中参数)
        p.apply_async(func, args=(i,))

    # 必须调用close函数,调用close后,就不能添加新的进程了
    p.close()

    # 主进程等到所有子进程执行完毕
    p.join()
    print ("end")

多线程

Python提供了threading、Thread(Python3 改名为_thread)多线程模块。

Thread是低级模块,threading是高级模块,threading对Thread进行了封装。threading模块提供Thread类来表示一个线程对象。

多线程实现

import threading


def func(i):
    print (i)


if __name__ == "__main__":
    # 创建线程实例 (线程调用函数,函数中的参数)
    t = threading.Thread(func, args=(1,))
    # 开始执行
    t.start()
    # 主进程等待线程执行完成
    t.join()

线程间数据同步

多线程间通过加锁的方式,来实现共享变量。

mutex = threading.lock()  #获取锁对象

mutex .acquire()  #加锁锁

mutex .release()  #释放锁

后果:(1)加锁的片段以单线程的方式在执行,大大降低了效率。

           (2)由于每个线程可以添加不同的锁,所以会造成死锁的问题。

local_thread = threading.local() #通过调用local类,实例化得到一个全局对象,不同的线程使用这个对象存储的数据,其他线程不可见,是这个线程独有的

每个子线程使用全局对象local_thread ,但每个线程定义的属性local_thread .x是该线程独有的。

Python中多线程的弊处

python中的多线程其实是一个伪多线程,Python解释器在设计是有GIL全句锁,所以导致python的多线程在运行时只能用到1核CPU,无法使用多核。

PPython线程在执行前需要先获取GIL全局锁,然后每执行100行字节码,就需要释放锁,然后让其他的线程执行,所有python的多线程是交替执行的,即使100个线程跑在100核的CPU上,也只是用到了1核CPU。

推荐学习多进程文档:https://www.liaoxuefeng.com/wiki/1016959663602400/1017628290184064

你可能感兴趣的:(Python)