Multiproceso en Python II
La limitación de los multiprocesos es que no comparten contexto por lo que no se pueden comunicar directamente o compartir variables, es equivalente a lanzar el programa de nuevo muchas veces. Dado que no comparten contexto no se puede comunicar directamente entre si
Cuando tenemos variables que compartimos como las listas, cuando se pasan a los procesos se replican, lo que es costoso en memoria, para esto multiprocessing nos ofrece Value y Array, Value nos permite compartir valores y Array nos permitir compartir arreglos. Z
"""
Autor: Carlos A Delgado
Fecha: 23 de Septiembre 2025
Ejemplo de multiprocessing en Python
"""
import time
from multiprocessing import Process
from multiprocessing import Array
from multiprocessing import Value
def suma_lista(ini, fin, l, v):
suma = 0
for i in range(ini, fin):
suma += l[i] # Suma elementos del segmento asignado
v.value = suma # Almacena resultado en variable compartida
def inicializar(ini, fin, l):
for i in range(ini, fin):
l[i] = i # Inicializa array con valores secuenciales
def main():
size = 10_000_000
l = Array("l", size) # Crea array compartido de tipo long
inicializar(0, size, l)
print(l[:20]) # Muestra primeros 20 elementos
# Ejecución secuencial
ini = time.time()
print(sum(l)) # Suma usando función built-in de Python
fin = time.time()
print("El tiempo secuencial es seg " + str(fin - ini))
# Ejecución paralela
ini = time.time()
v1 = Value("l") # Variable compartida tipo long para proceso 1
v2 = Value("l") # Variable compartida tipo long para proceso 2
v3 = Value("l") # Variable compartida tipo long para proceso 3
v4 = Value("l") # Variable compartida tipo long para proceso 4
# Divide el trabajo en 4 segmentos iguales
p1 = Process(target=suma_lista, args=(0, size // 4, l, v1))
p2 = Process(target=suma_lista, args=(size // 4, 2 * size // 4, l, v2))
p3 = Process(target=suma_lista, args=(2 * size // 4, 3 * size // 4, l, v3))
p4 = Process(target=suma_lista, args=(3 * size // 4, size, l, v4))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join()
fin = time.time()
print(v1.value + v2.value + v3.value + v4.value) # Combina resultados
print("El tiempo en 4 procesos en s es " + str(fin - ini))
if __name__ == "__main__":
main()
graph TD
A[Proceso Principal] --> B{Memoria}
subgraph "Caso numpy.array"
B --> C[Array numpy en memoria privada]
A --> D[Proceso Hijo 1]
A --> E[Proceso Hijo 2]
A --> F[Proceso Hijo 3]
A --> G[Proceso Hijo 4]
D --> H[Copia completa del array]
E --> I[Copia completa del array]
F --> J[Copia completa del array]
G --> K[Copia completa del array]
end
subgraph "Caso multiprocessing.Array"
B --> L[Array compartido en memoria]
A --> M[Proceso Hijo 1]
A --> N[Proceso Hijo 2]
A --> O[Proceso Hijo 3]
A --> P[Proceso Hijo 4]
M --> L
N --> L
O --> L
P --> L
end
subgraph "Variables de resultado"
Q[Value v1] --> R[Suma parcial 1]
S[Value v2] --> T[Suma parcial 2]
U[Value v3] --> V[Suma parcial 3]
W[Value v4] --> X[Suma parcial 4]
end
R --> Y[Resultado final]
T --> Y
V --> Y
X --> Y
Diferencia entre numpy.array y multiprocessing.Array:
- numpy.array: Cada proceso hijo recibe una copia completa del array en memoria separada, consumiendo 4× la memoria original y requiriendo serialización/deserialización
- multiprocessing.Array: Todos los procesos acceden al mismo array en memoria compartida, evitando duplicación y permitiendo acceso concurrente sincronizado
El código usa Array("l", size) para crear un array compartido de tipo long, donde "l" indica el tipo de dato. Los procesos acceden directamente a los mismos datos en memoria, optimizando el uso de recursos. Las variables Value("l") almacenan los resultados parciales de forma compartida, permitiendo la combinación final sin necesidad de comunicación adicional.