猪行天下之Python基础——9.3 Python多线程与多进程(下)(三)

简介: 内容简述: 1、multiprocess模块详解

运行结果如下


单线程处理结果: 999985000050000
单线程处理耗时: 0.10726284980773926
多线程处理结果: 999985000050000
多线程处理耗时: 0.13849401473999023
多进程处理结果: 999985000050000
多进程处理耗时: 0.041596174240112305


从上面的结果可以明显看出在处理CPU密集型任何时,多进程更优。


2.Value和Array


两者是通过「共享内存」的方式来共享数据的,前者用于需要共享单个值后者用于

共享多个值(数组),构造函数的第一个元素数据类型第二个元素。数据类型对照如表所示。


标记 数据类型 标记 数据类型
'c' ctypes.c_char 'u' ctypes.c_wchar
'b' ctypes.c_byte 'B' ctypes.c_ubyte
'h' ctypes.c_short 'H' ctypes.c_ushort
'i' ctypes.c_int 'I' ctypes.c_uint
'l' ctypes.c_long 'L' ctypes.c_ulong
'f' ctypes.c_float 'd' ctypes.c_double


使用代码示例如下


import multiprocessing as mp
def do_something(num, arr):
    num.value += 1
    for i in range(len(arr)):
        arr[i] = arr[i] * 2
if __name__ == '__main__':
    value = mp.Value('i', 1)
    array = mp.Array('i', range(5))
    print("刚开始的值:", value.value, array[:])
    # 创建进程1
    p1 = mp.Process(target=do_something, args=(value, array))
    p1.start()
    p1.join()
    print("进程1操作后的值:", value.value, array[:])
    # 创建进程2
    p2 = mp.Process(target=do_something, args=(value, array))
    p2.start()
    p2.join()
    print("进程2操作后的值:", value.value, array[:])


运行结果如下


刚开始的值: 1 [0, 1, 2, 3, 4]
进程1操作后的值: 2 [0, 2, 4, 6, 8]
进程2操作后的值: 3 [0, 4, 8, 12, 16]


3.Manager


Python还为我们提供更加强大的数据共享类,支持更丰富的数据类型,比如Value、Array、dict、list、Lock、Semaphore等等,另外Manager还可以共享类的实例对象。有一点要注意:进程间通信应该尽量避免使用共享数据的方式!


使用代码示例如下


import multiprocessing as mp
import os
import time
def do_something(dt):
    dt[os.getpid()] = int(time.time())
    print(data_dict)
if __name__ == '__main__':
    manager = mp.Manager()
    data_dict = manager.dict()
    for i in range(3):
        p=mp.Process(target=do_something,args=(data_dict,))
        p.start()
        p.join()


运行结果如下


{5432: 1533200189}
{5432: 1533200189, 5433: 1533200189}
{5432: 1533200189, 5433: 1533200189, 5434: 1533200189}


4.Pipe


管道简化版的Queue,通过Pipe()构造函数可以创建一个进程通信用的管道对象默认双向,意味着使用管道只能同时开启两个进程!如果想设置单向,可以添加参数「duplex=False」,双向即可发送也可接受,但是只允许前面的端口用于接收,后面的端口用于发送。管道对象发送和接收信息的函数依次为send()和recv()。使用代码示例如下


import multiprocessing as mp
def p_1(p):
    p.send("你好啊!")
    print("P1-收到信息:", p.recv())
def p_2(p):
    print("P2-收到信息:", p.recv())
p.send("你也好啊!")
if __name__ == '__main__':
    pipe = mp.Pipe()
    p1 = mp.Process(target=p_1, args=(pipe[0],))
    p2 = mp.Process(target=p_2, args=(pipe[1],))
    p1.start()
    p2.start()
    p1.join()
    p2.join()


运行结果如下


P2-收到信息: 你好啊!
P1-收到信息: 你也好啊!


关于多进程加锁的,可以参见前面多进程加锁部分内容,这里就不重复讲解了,只是导包换成了multiprocessing,比如threading.Lock换成了multiprocessing.Lock


相关文章
|
8天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
2天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
17 0
|
17天前
|
安全 Linux API
Android进程与线程
Android进程与线程
18 0
|
17天前
|
数据采集 Java API
python并发编程: Python使用线程池在Web服务中实现加速
python并发编程: Python使用线程池在Web服务中实现加速
17 3
python并发编程: Python使用线程池在Web服务中实现加速
|
10天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
21天前
|
存储 缓存 NoSQL
Redis单线程已经很快了6.0引入多线程
Redis单线程已经很快了6.0引入多线程
31 3
|
24天前
|
消息中间件 安全 Linux
线程同步与IPC:单进程多线程环境下的选择与权衡
线程同步与IPC:单进程多线程环境下的选择与权衡
57 0
|
1月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
1月前
|
安全 编译器 C#
C#学习相关系列之多线程---lock线程锁的用法
C#学习相关系列之多线程---lock线程锁的用法
|
1月前
|
Java C#
C#学习系列相关之多线程(五)----线程池ThreadPool用法
C#学习系列相关之多线程(五)----线程池ThreadPool用法