使用Red Hat Satellite API的python multiprocessing.Pool值不正确

时间:2013-11-13 09:38:35

标签: python multiprocessing

我正在使用Red Hat Satellite API为RHEL4,5,6系统创建组。没有多处理它工作正常,但我想加快过程,所以想到使用multiprocessing.Pool,但不知何故得到不正确的值。这是我的代码:

CLIENT = xmlrpclib.Server(SATELLITE_URL, verbose=0)
KEY = CLIENT.auth.login(SATELLITE_LOGIN, SATELLITE_PASSWORD)

def ADD_SYSTEMS(ITEM):
    SYSTEMID = ITEM['id']
    SYSTEMNAME = ITEM['name']
    RUNNINGKERNEL = CLIENT.system.getRunningKernel(KEY,SYSTEMID)
    print type(RUNNINGKERNEL), RUNNINGKERNEL, multiprocessing.current_process().name
    if RUNNINGKERNEL.startswith("2.6.32"):
    CLIENT.systemgroup.addOrRemoveSystems(KEY,"ALL_RHEL6_SYSTEMS",SYSTEMID,True)
    elif RUNNINGKERNEL.startswith("2.6.18"):
    CLIENT.systemgroup.addOrRemoveSystems(KEY,"ALL_RHEL5_SYSTEMS",SYSTEMID,True)
    else:
    CLIENT.systemgroup.addOrRemoveSystems(KEY,"ALL_RHEL4_SYSTEMS",SYSTEMID,True)

if __name__ == '__main__':
    ACTIVESYSTEMS = CLIENT.system.listActiveSystems(KEY)
    PSIZE = multiprocessing.cpu_count()
    P = multiprocessing.Pool(processes=PSIZE)
    P.map(ADD_SYSTEMS, ACTIVESYSTEMS)
    P.close()
    P.join()

CLIENT.auth.logout(KEY)

当我运行代码时,我收到以下错误,

<type 'str'> 2.6.18-348.12.1.el5 PoolWorker-1
<type 'str'> 2.6.18-348.18.1.el5 PoolWorker-8
<type 'str'> 2.6.18-371.1.2.el5 PoolWorker-9
<type 'str'> 2.6.18-348.16.1.el5 PoolWorker-10
<type 'str'> 2.6.18-348.16.1.el5 PoolWorker-3
<type 'str'> 2.6.9-100.ELsmp PoolWorker-8
<type 'str'> 2.6.18-371.1.2.el5 PoolWorker-4
<type 'str'> 2.6.32-358.23.2.el6.x86_64 PoolWorker-2
<type 'int'> 1 PoolWorker-11
Traceback (most recent call last):
  File "./1rhnGroupMaintenance.py", line 42, in <module>
    P.map(ADD_SYSTEMS, ACTIVESYSTEMS)
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 227, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 528, in get
    raise self._value
AttributeError: 'int' object has no attribute 'startswith'
<type 'str'> 2.6.9-100.ELsmp PoolWorker-1

如果我在函数中注释if..elif..else块,则print将显示正确的值。我不知道我在这里做错了什么。请帮忙。

3 个答案:

答案 0 :(得分:0)

正如您在循环中看到的那样,RUNNINGKERNEL的值为int的一个案例:

<type 'int'> 1 PoolWorker-11

你试图在那个错误的整数上使用str.startswith

>>> (1).startswith

Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    (1).startswith
AttributeError: 'int' object has no attribute 'startswith'

要解决此问题,您可以检查RUNNINGKERNEL的类型,并根据该类型添加一些新条件。

if isinstance(RUNNINGKERNEL, int):
   #do something
elif isinstance(RUNNINGKERNEL, str):
   if RUNNINGKERNEL.startswith("2.6.32"):
      ...

答案 1 :(得分:0)

看起来像这个远程过程调用

RUNNINGKERNEL = CLIENT.system.getRunningKernel(KEY,SYSTEMID)

有时会返回一个字符串(“kernel something”),而某个特定的键返回一个int(1)

尝试在int上使用startswith失败,因为它是一个字符串方法

我会检查罪魁祸首id上远程过程调用的实际答案,或者如果答案是预期的,请确保你实际处理字符串

RUNNINGKERNEL = str(CLIENT.system.getRunningKernel(KEY,SYSTEMID))

或明确处理int:

的情况

如果isinstance(RUNNINGKERNEL,int):       通过    else isinstance(RUNNINGKERNEL,str):       #你的一堆ifs

答案 2 :(得分:0)

似乎问题在于版本5.4.1中的Red Hat Satellite API调用在某个时间点受到限制。我没有找到任何有关此限制的Red Hat官方文档,但是当我与2名工作人员一起测试并且代码工作正常时。我从我的工作站运行代码,其中有12个CPU内核,Satellite API可以处理这些代码,并为一些调用返回1。我将不得不硬编码工作进程的数量。