【工程实践】python实现多进程

这篇具有很好参考价值的文章主要介绍了【工程实践】python实现多进程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 多线程与多进程

        Python中比较常见的并发方式主要有两种:多线程和多进程。

1-1 多线程

        多线程即在一个进程中启动多个线程执行任务。一般来说使用多线程可以达到并行的目的,但由于Python中使用了全局解释锁GIL的概念,导致Python中的多线程并不是并行执行,而是“交替执行”。类似于下图。

【工程实践】python实现多进程

        所以Python中的多线程适合IO密集型任务,而不适合计算密集型任务。Python提供两组多线程接口,一是thread模块_thread,提供低等级接口。二是threading模块,提供更容易使用的基于对象的接口,可以继承Thread对象来实现线程,此外其还提供了其它线程相关的对象,例如Timer,Lock等。

1-2 多进程

         由于Python中GIL的原因,对于计算密集型任务,Python下比较好的并行方式是使用多进程,这样可以非常有效的使用CPU资源。当然同一时间执行的进程数量取决你电脑的CPU核心数。在支持多任务操作系统中,一个应用程序会被分解成多个独立运行的较小的程序。操作系统会将这些线程分配到多核处理器,以提升系统性能。执行过程如下图。每个进程都拥有自己的地址空间、内存、文件描述符和其他系统资源。多进程的好处在于可以使程序并行执行,从而提高程序的运行效率。

【工程实践】python实现多进程

        如果每个子进程执行需要消耗的时间非常短(执行+1操作等),这不必使用多进程,因为进程的启动关闭也会耗费资源。当然使用多进程往往是用来处理CPU密集型(科学计算)的需求,如果是IO密集型(文件读取,爬虫等)则可以使用多线程去处理。

2 多进程实现

2-1 multiprocessing

2-1-1 Process

        multiprocessing模块提供了一个Process类,可以用来创建和管理进程。下面是一个简单的示例。

multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
参数介绍:
    1. group默认为None(目前未使用)
    2. target代表调用对象,即子进程执行的任务
    3. name为进程名称
    4. args调用对象的位置参数元组,args=(value1, value2, ...)
    5. kwargs调用对象的字典,kwargs={key1:value1, key2:value2, ...}

    6. daemon表示进程是否为守护进程,布尔值    
方法介绍:

    1.Process.start() 启动进程,并调用子进程中的run()方法

    2. Process.run() 进程启动时运行的方法,在自定义时必须要实现该方法       

    3.Process.terminate() 强制终止进程,不进行清理操作,如果Process创建了子进程,会导致该进程变成僵尸进程  

    4.Process.join() 阻塞进程使主进程等待该进程终止  

    5.Process.kill() 与terminate()相同  

    6.Process.is_alive() 判断进程是否还存活,如果存活,返回True  

    7.Process.close() 关闭进程对象,并清理资源,如果进程仍在运行则返回错误  

import multiprocessing

def worker(x,y,z):
    """该函数将在子进程中执行"""
    print(x,y,z)

if __name__ == '__main__':
    # 创建子进程
    p = multiprocessing.Process(target=worker,args = (1,2,3))
    # 启动子进程
    p.start()
    # 等待子进程结束
    p.join()

        在上面的代码中,worker函数将在子进程中执行。首先,创建了一个Process对象,指定target参数为worker函数。然后,通过调用start方法启动子进程,最后调用join方法等待子进程结束。

        示例:        

def get_final_result(chunk):
    #以任意一chunk为实例进行处理,其余的chunk均按照此逻辑运行
    for index in tqdm((range(len(chunk)))) :
        str_data = chunk[index]
        test_dict = ast.literal_eval(str_data)
        text = test_dict['text'].split('航空公司不会')[0].split('如需')[0].split('若需')[0].split('服务电话')[0].split('服务热线')[0].split('热线')[0].split('客服电话')[0].split('请拨打')[0].split('请打')[0].split('致电')[0].split('联系')[0].split('来电')[0]
        text = text.replace('(','').replace(')','').replace('(','').replace(')','')
        label = test_dict['label']
        result = get_result(text)
        write_file(result)
    
if __name__ == "__main__":
    #读入航班信息
    file_path = '/home/zhenhengdong/WORk/SMS_Parsing/规则/Data/原始_airports.json'
    with open(file_path, 'r', encoding='utf8') as f:
        json_filedata = f.readlines()
    #启动进程池
    pool = multiprocessing.Pool(20)
    #划分chunk
    chunks = [json_filedata[start:start + 1000] for start in range(0, len(json_filedata), 1000)]
    #将所有的chunk统一传进处理函数中
    results = pool.map(get_final_result,chunks)

2-1-2 Pool

        如果需要创建大量的进程,那么使用Process类可能会导致系统资源的浪费。此时,可以使用Pool类来创建进程池。下面是一个简单的示例。

import multiprocessing

def worker(num):
    """该函数将在子进程中执行"""
    print('Worker %d' % num)

if __name__ == '__main__':
    # 创建进程池
    pool = multiprocessing.Pool(4)
    # 启动进程池中的进程
    pool.map(worker, range(10))
    # 关闭进程池
    pool.close()
    # 等待进程池中的进程结束
    pool.join()

        在上面的代码中,Pool类的构造函数中指定了进程池的大小为4,然后通过调用map方法来启动进程池中的进程。map方法会将worker函数和range(10)序列中的每个元素一一对应,然后将它们作为参数传递给进程池中的进程。最后,调用close方法关闭进程池,并调用join方法等待所有进程结束。

2-2 partial

        针对一些特殊需求,需要对map函数传递两个或者多个参数,这时单纯的map函数已经不能满足需求了,就需要借助偏函数来完成。

        偏函数是python自带的包,直接导入就能用。偏函数partial的第一个参数就是所承载的原函数,之后原函数的参数再依次传入partial函数。文章来源地址https://www.toymoban.com/news/detail-494860.html

from functools import partial
#定义
def add_num(x, y):
    return x + y
# 承载add_num函数,并传入第一个参数
para = partial(add_num, 3)
# 传递第二个参数,就是把2传给para
result = para(2)
# 输出最后的结果
print(result)

2-3 Pool与partial处理数据​​​​​​​

import multiprocessing
import functools

def drop_app_index(drop_list, chunk):
    for element in tqdm(drop_list):
        chunk = chunk.drop(index = chunk[(chunk.pkg_name == element)].index.tolist())
    return chunk

pool = multiprocessing.Pool(20)
drop_list = list(data['pkg_name'].value_counts().keys())[600:]
print(len(drop_list))
# 将DataFrame拆分为多个片段
chunks = [data.iloc[start:start + 10000] for start in range(0, len(data), 10000)]
#偏函数
g_with_a = functools.partial(drop_app_index, drop_list)
results = pool.map(g_with_a,chunks)
#results = pool.map(partial(process_chunk,drop_list),chunks)
# 合并所有处理结果
df_result = pd.concat(results)
data = df_result.reset_index(drop=True)

到了这里,关于【工程实践】python实现多进程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python多任务教程:进程、线程、协程

    进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程序、数据集合和进程控制块三部分组成。程序用于描述进

    2024年02月12日
    浏览(41)
  • 8.0 Python 使用进程与线程

    python 进程与线程是并发编程的两种常见方式。进程是操作系统中的一个基本概念,表示程序在操作系统中的一次执行过程,拥有独立的地址空间、资源、优先级等属性。线程是进程中的一条执行路径,可以看做是轻量级的进程,与同一个进程中的其他线程共享相同的地址空间

    2024年02月13日
    浏览(43)
  • python多进程与多线程

    1.1 GIL 全局解释器锁 其他语言,CPU是多核时是支持多个线程同时执行。但在Python中,无论是单核还是多核,同时只能由一个线程在执行。其根源是GIL的存在。GIL的全称是Global Interpreter Lock(全局解释器锁),来源是Python设计之初的考虑,为了数据安全所做的决定。某个线程想要执

    2024年02月05日
    浏览(41)
  • python-16-线程池和进程池python并发编程

    Python ThreadPoolExecutor线程池 线程池的基本原理是什么? 利用Python快速实现一个线程池,非常简单 Python并发编程专题 一、为什么要引入并发编程? 场景1:一个网络爬虫,按顺序爬取花了1小时,采用并发下载减少到20分钟! 场景2:一个APP应用,优化前每次打开页面需要3秒,采

    2024年02月04日
    浏览(39)
  • 【Python】多进程线程与CPU核数

    多进程数量设置为CPU核数,或者略小于CPU核数; 多线程数量,如果是CPU密集任务设为1;如果是IO密集设为合理的值; IO密集型:系统运作,大部分的状况是CPU 在等I/O (硬盘/内存)的读/写。 计算密集型:大部份时间用来做计算、逻辑判断等CPU 动作的程序称之CPU 密集型。 对

    2024年01月16日
    浏览(38)
  • 【Python爬虫与数据分析】进程、线程、协程

    目录 一、概述 二、进程的创建 三、线程的创建 四、协程的创建 五、全局变量的共享问题 六、消息队列与互斥锁 七、池化技术 进程是系统分配资源的基本单位,线程是CPU调度的基本单位。 一个进程可包含多个线程,一个线程可包含多个协程,协程就是最小的任务执行单位

    2024年02月13日
    浏览(41)
  • 一文掌握Python多线程与多进程

    并发是今天计算机编程中的一项重要能力,尤其是在面对需要大量计算或I/O操作的任务时。Python 提供了多种并发的处理方式,本篇文章将深入探讨其中的两种:多线程与多进程,解析其使用场景、优点、缺点,并结合代码例子深入解读。 Python中的线程是利用 threading 模块实现

    2024年02月09日
    浏览(45)
  • Python中进程和线程到底有什么区别?

    python 安装包+资料:点击此处跳转文末名片获取 一、进程和线程的关系 线程与进程的区别可以归纳为以下4点: 地址空间和其它资源(如打开文件) :进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。 通信 :进程间通信IPC,线程间可以直接读写

    2023年04月08日
    浏览(42)
  • [Python系列] 线程、协程、进程和分布式

            我们在写脚本的时候,经常是单线程跑完了全部,毕竟自顶向下按照我们约定的方法运行下去是最规范的。但是很多时候,比如说合法地爬取一些网页信息,图片和资料啊,或者说一些合法的网络请求,读写文件之类的。如果还是单线程地one by one,那么将会影响我们

    2024年02月16日
    浏览(36)
  • Python渗透测试编程基础——线程、进程与协程

    目录  一、进程与线程的概念 1.进程 2.线程 3.进程和线程的关系 4.任务执行方式 二、Python中的Threading模块 1.线程模块介绍 2.Threading介绍 (1)方法和属性 (2)类方法 三、线程简单编写 1.流程 2.创建线程 (1)方法一 (2)方法二 3.例子 四、守护线程 五、线程同步技术 1.线程

    2024年02月01日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包