python多文件共享变量_Python多处理和共享变量

我不是python的专家,但我已经设法写下了一个多处理代码,它在我的PC中使用了我所有的cpus和内核.我的代码加载了一个非常大的数组,大约1.6 GB,我需要在每个进程中更新数组.幸运的是,更新包括在图像中添加一些人造恒星,每个过程都有一组不同的图像位置,可以添加人造恒星.

图像太大,每次调用一个进程时我都无法创建一个新图像.我的解决方案是在共享内存中创建一个变量,我节省了大量内存.由于某种原因,它适用于90%的图像,但有些区域是我的代码在我之前发送到流程的某些位置添加随机数.它与我创建共享变量的方式有关吗?在我的代码执行过程中,这些进程是否相互干扰?

奇怪的是,当使用单个cpu和单核时,图像是100%完美的,并且图像中没有添加随机数.你建议我在多个进程之间共享一个大型数组吗?这是我的代码的相关部分.请在定义变量im_data时读取行.

import warnings

warnings.filterwarnings("ignore")

from mpl_toolkits.mplot3d import Axes3D

from matplotlib import cm

import matplotlib.pyplot as plt

import sys,os

import subprocess

import numpy as np

import time

import cv2 as cv

import pyfits

from pyfits import getheader

import multiprocessing,Queue

import ctypes

class Worker(multiprocessing.Process):

def __init__(self,work_queue,result_queue):

# base class initialization

multiprocessing.Process.__init__(self)

# job management stuff

self.work_queue = work_queue

self.result_queue = result_queue

self.kill_received = False

def run(self):

while not self.kill_received:

# get a task

try:

i_range,psf_file = self.work_queue.get_nowait()

except Queue.Empty:

break

# the actual processing

print "Adding artificial stars - index range=",i_range

radius=16

x_c,y_c=( (psf_size[1]-1)/2,(psf_size[2]-1)/2 )

x,y=np.meshgrid(np.arange(psf_size[1])-x_c,np.arange(psf_size[2])-y_c)

distance = np.sqrt(x**2 + y**2)

for i in range(i_range[0],i_range[1]):

psf_xy=np.zeros(psf_size[1:3],dtype=float)

j=0

for i_order in range(psf_order+1):

j_order=0

while (i_order+j_order < psf_order+1):

psf_xy += psf_data[j,:,:] * ((mock_y[i]-psf_offset[1])/psf_scale[1])**i_order * ((mock_x[i]-psf_offset[0])/psf_scale[0])**j_order

j_order+=1

j+=1

psf_factor=10.**( (30.-mock_mag[i])/2.5)/np.sum(psf_xy)

psf_xy *= psf_factor

npsf_xy=cv.resize(psf_xy,(npsf_size[0],npsf_size[1]),interpolation=cv.INTER_LANCZOS4)

npsf_factor=10.**( (30.-mock_mag[i])/2.5)/np.sum(npsf_xy)

npsf_xy *= npsf_factor

im_rangex=[max(mock_x[i]-npsf_size[1]/2,0),min(mock_x[i]-npsf_size[1]/2+npsf_size[1],im_size[1])]

im_rangey=[max(mock_y[i]-npsf_size[0]/2,min(mock_y[i]-npsf_size[0]/2+npsf_size[0],im_size[0])]

npsf_rangex=[max(-1*(mock_x[i]-npsf_size[1]/2),min(-1*(mock_x[i]-npsf_size[1]/2-im_size[1]),npsf_size[1])]

npsf_rangey=[max(-1*(mock_y[i]-npsf_size[0]/2),min(-1*(mock_y[i]-npsf_size[0]/2-im_size[0]),npsf_size[0])]

im_data[im_rangey[0]:im_rangey[1],im_rangex[0]:im_rangex[1]] = 10.

self.result_queue.put(id)

if __name__ == "__main__":

n_cpu=2

n_core=6

n_processes=n_cpu*n_core*1

input_mock_file=sys.argv[1]

print "Reading file ",im_file[i]

hdu=pyfits.open(im_file[i])

data=hdu[0].data

im_size=data.shape

im_data_base = multiprocessing.Array(ctypes.c_float,im_size[0]*im_size[1])

im_data = np.ctypeslib.as_array(im_data_base.get_obj())

im_data = im_data.reshape(im_size[0],im_size[1])

im_data[:] = data

data=0

assert im_data.base.base is im_data_base.get_obj()

# run

# load up work queue

tic=time.time()

j_step=np.int(np.ceil( mock_n*1./n_processes ))

j_range=range(0,mock_n,j_step)

j_range.append(mock_n)

work_queue = multiprocessing.Queue()

for j in range(np.size(j_range)-1):

if work_queue.full():

print "Oh no! Queue is full after only %d iterations" % j

work_queue.put( (j_range[j:j+2],psf_file[i]) )

# create a queue to pass to workers to store the results

result_queue = multiprocessing.Queue()

# spawn workers

for j in range(n_processes):

worker = Worker(work_queue,result_queue)

worker.start()

# collect the results off the queue

while not work_queue.empty():

result_queue.get()

print "Writing file ",mock_im_file[i]

hdu[0].data=im_data

hdu.writeto(mock_im_file[i])

print "%f s for parallel computation." % (time.time() - tic)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 中,共享变量通常指的是可以在多个函数或线程之间直接访问和修改的变量。这可能会导致并发问题,因为没有适当的同步机制,如果多个部分同时改变同一个值,结果可能是不可预测的。Python 提供了一些工具来处理这种情况: 1. **全局变量**:如果你确实需要在所有函数中共享数据,可以定义为全局变量(用 `global` 关键字声明)。但请注意,全局变量在程序的所有模块间都是可见的,因此应谨慎使用,避免副作用。 ```python # 全局变量示例 global_var = 0 def increment(): global global_var global_var += 1 increment() print(global_var) # 输出:1 ``` 2. **模块级作用域**:在模块内部定义的变量通常是共享的,但在不同文件中使用时需注意作用域。 3. **进程/线程共享**: 使用 `multiprocessing` 或 `threading` 模块时,可以通过 `Manager` 对象创建共享的数据结构,如 `Value`, `Array`, `Lock` 等,它们提供了更安全的方式来共享数据。 ```python from multiprocessing import Manager manager = Manager() shared_list = manager.list([0, 0]) def worker(index): shared_list[index] += 1 processes = [Process(target=worker, args=(i,)) for i in range(2)] for p in processes: p.start() p.join() print(shared_list) # 输出:[1, 1] ``` 4. **类属性与实例属性**:在类中,实例变量(即成员变量)默认是在每个实例上独立存储的。但如果设置为 `@classmethod` 或 `@staticmethod`,则会成为类的共享属性。 5. **命名空间管理**:Python 遵循词法作用域规则,通过局部作用域、闭包等方式可以控制变量的可见性和访问权限,减少意外的共享。 然而,推荐在设计复杂系统时优先考虑使用适当的数据结构(如列表、字典等)、函数参数传递或消息传递(队列、事件、信号量),而不是直接共享变量,以便更好地维护代码的清晰性和一致性。对于并发编程,了解如何使用锁(如 `Lock`、`RLock` 或 `Semaphore`)和其他同步原语是非常重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值