Python 如何为多处理pickle pyEphem对象?
我正在尝试计算卫星的一些值,数据生成需要相当长的时间,所以我想使用多处理来实现这一点 问题是我从pyEphem得到这个错误,TypeError:cannotpickle ephem.EarthSatellite对象。pyEphem对象不用于我想要并行化的函数中 这是我的代码示例文件 这是我的主文件: main.py 回溯:Python 如何为多处理pickle pyEphem对象?,python,multiprocessing,pickle,pyephem,dill,Python,Multiprocessing,Pickle,Pyephem,Dill,我正在尝试计算卫星的一些值,数据生成需要相当长的时间,所以我想使用多处理来实现这一点 问题是我从pyEphem得到这个错误,TypeError:cannotpickle ephem.EarthSatellite对象。pyEphem对象不用于我想要并行化的函数中 这是我的代码示例文件 这是我的主文件: main.py 回溯: 原因是这样的。。。当您尝试pickle一个函数时,它可以尝试pickle全局,因此全局命名空间中的任何内容都会被pickle,以防您的函数引用全局中的某个内容-是的,这是出乎
原因是这样的。。。当您尝试pickle一个函数时,它可以尝试pickle全局,因此全局命名空间中的任何内容都会被pickle,以防您的函数引用全局中的某个内容-是的,这是出乎意料的,但事实就是这样。因此,一个简单的修复方法是将要pickle的函数隔离到另一个文件中-在本例中,将多处理内容放在一个文件中,将另一个代码放在另一个文件中。。。因此,泡菜者在全球范围内的斗争就更少了。另一个可能有用的方法是使用多进程而不是多进程-多进程使用dill序列化程序而不是pickle,因此,您有更好的机会序列化将在池中的工作线程之间发送的对象。您可能希望main中Sats的第一个参数有一个列表或类似的列表。显示错误发生的行和完整的回溯。确保您可以自己运行此代码以获得预期的错误。在我的代码中,我正在阅读这些参数来自一个文本文件,它们只用于pyEphem对象的初始化一次,这很好。只需传入一个在示例中有意义的值。目前,你正在为tle传递字符串,但我很确定这是不对的。通过运行代码进行检查。
import ephem
import numpy
import math
import multiprocessing as mp
from SampleSats import Sats
GPS_Satellites = []
SFrames = 1
TLE = ["GPS BIIR-3 (PRN 11)",
"1 25933U 99055A 18090.43292845 -.00000054 00000-0 00000+0 0 9994",
"2 25933 51.8367 65.0783 0165007 100.2058 316.9161 2.00568927135407"]
# PRN TLE file from CelesTrak
GPS_Satellites.append(Sats(TLE))
Position = ephem.Observer()
Position.date = '2018/3/31 00:00' # 1st January 2018 at 00:00 UTC
Position.lon, Position.lat = "36.845663", "-37.161123" # Coordinates for desired Position
# Calculate Satellites
for Frames in range(SFrames):
print("Generate Signals for Time: ", Position.date)
for Sats in GPS_Satellites: # par
Sats.compute(Position)
if ((float(repr(Sats.ephemeris.alt)) * 180 / math.pi) < 5) or ( # Calculate angle above horizon
(float(repr(Sats.ephemeris.alt)) * 180 / math.pi) > 90):
Sats.visible = 0
else:
Sats.visible = 1
with mp.Pool() as pool:
for value, obj in zip(pool.map(Sats.genSignal, GPS_Satellites), GPS_Satellites):
obj.Signal = value
Position.date = Position.date + 6*ephem.second # 1 Subframe is 6 seconds long
import ephem
import numpy
class Sats:
"""Save Satellites as Objects"""
def __init__(self, tle):
""":param tle: Two Line Element for ephemeris data also used to get PRN Number from name"""
self.ephemeris = ephem.readtle(tle[0], tle[1], tle[2])
self.visible = 1
self.subframes = 0
self.CAseq = [x for x in range(1023)]
self.Out = []
self.Signal = numpy.zeros(int(300*20*1023), dtype=numpy.int8)
def compute(self, pos):
self.ephemeris.compute(pos)
self.Out.append(numpy.arange(0, 299, 1))
self.subframes += 1
def calcData(self, bit, prn):
return (self.Out[self.subframes - 1].item(0)[0][bit] + self.CAseq[prn]) % 2
def genSignal(self):
if(self.visible == 1):
for bit in range(300): # 1 Subframe is 300 Bit long
for x in range(20): # The PRN Sequence reoccurs every ms -> 20 times per pit
for prn in range(1023): # length of the prn sequence
self.Signal[bit*x*prn] = (-1 if (self.calcData(bit, prn))==0 else 1)
else:
self.Signal = numpy.zeros(300*20*1023)
return self.Signal
Traceback (most recent call last):
File "C:/Users/PATH_TO_PROJECT/SampleTest.py", line 33, in <module>
for value, obj in zip(pool.map(Sats.genSignal, GPS_Satellites), GPS_Satellites):
File "C:\Program Files\Python36\lib\multiprocessing\pool.py", line 266, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "C:\Program Files\Python36\lib\multiprocessing\pool.py", line 644, in get
raise self._value
File "C:\Program Files\Python36\lib\multiprocessing\pool.py", line 424, in _handle_tasks
put(task)
File "C:\Program Files\Python36\lib\multiprocessing\connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "C:\Program Files\Python36\lib\multiprocessing\reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
TypeError: can't pickle ephem.EarthSatellite objects