对于想了解使用multiprocessing.Manager.list而不是真实列表会使计算耗时的读者,本文将是一篇不可错过的文章,并且为您提供关于Appium-multiprocessing.poo
对于想了解使用multiprocessing.Manager.list而不是真实列表会使计算耗时的读者,本文将是一篇不可错过的文章,并且为您提供关于Appium - multiprocessing.pool.MaybeEncodingError-【 “Can’t pickle local object ‘PoolManager.__init...、multiprocessing--强大Manage、multiprocessing.Manager()dict()setdefault()是否损坏?、multiprocessing.Manager()。dict()。setdefault()是否损坏?的有价值信息。
本文目录一览:- 使用multiprocessing.Manager.list而不是真实列表会使计算耗时
- Appium - multiprocessing.pool.MaybeEncodingError-【 “Can’t pickle local object ‘PoolManager.__init...
- multiprocessing--强大Manage
- multiprocessing.Manager()dict()setdefault()是否损坏?
- multiprocessing.Manager()。dict()。setdefault()是否损坏?
使用multiprocessing.Manager.list而不是真实列表会使计算耗时
我想尝试multiprocessing
从本示例开始的不同使用方式:
$ cat multi_bad.py
import multiprocessing as mp
from time import sleep
from random import randint
def f(l,t):
# sleep(30)
return sum(x < t for x in l)
if __name__ == '__main__':
l = [randint(1,1000) for _ in range(25000)]
t = [randint(1,1000) for _ in range(4)]
# sleep(15)
pool = mp.Pool(processes=4)
result = pool.starmap_async(f,[(l,x) for x in t])
print(result.get())
这里l
是一个列表,当生成4个进程时,该列表将被复制4次。为了避免这种情况,文档页面提供了使用队列,共享数组或使用创建的代理对象的信息multiprocessing.Manager
。对于最后一个,我更改了的定义l
:
$ diff multi_bad.py multi_good.py
10c10,11
< l = [randint(1,1000) for _ in range(25000)]
---
> man = mp.Manager()
> l = man.list([randint(1,1000) for _ in range(25000)])
结果看起来仍然正确,但是执行时间却大大增加,以至于我做错了什么:
$ time python multi_bad.py
[17867,11103,2021,17918]
real 0m0.247s
user 0m0.183s
sys 0m0.010s
$ time python multi_good.py
[3609,20277,7799,24262]
real 0m15.108s
user 0m28.092s
sys 0m6.320s
文档确实说这种方法比共享数组要慢,但这感觉很不对。我也不确定如何配置此文件,以获取有关正在发生的事情的更多信息。我想念什么吗?
PS与共享数组,我得到的时间低于0.25s。
PPS这是在Linux和Python 3.3上。
Appium - multiprocessing.pool.MaybeEncodingError-【 “Can’t pickle local object ‘PoolManager.__init...
公司同事学习自动化新装环境后,run多进程测试用例时出错:
multiprocessing.pool.MaybeEncodingError: Error sending result: ’<appium.webdriver.webdriver.WebDriver (session=“261019ae-3776-4a78-aa2c-b24bb64ec62e”)>’. Reason: ’AttributeError(“Can’t pickle local object ‘PoolManager.__init__.<locals>.<lambda>‘“)’
同一份代码,我本地并没有这种情况
在网上搜索到三种方法:
1.用线程替换进程
2.可以使用copy_reg来规避上面的异常.
3.dill 或pathos.multiprocesssing :use ''import pathos.multiprocesssing'', instead of ''import multiprocessing''. pathos.multiprocessing is a fork of multiprocessing that uses dill. dill can serialize almost anything in python, so you are able to send a lot more around in parallel.
最开始采用了方法3:use ''import pathos.multiprocesssing'', instead of ''import multiprocessing'' ,然后程序并不在抛出该错误,但是启动case后,appium启动driver后便不在干活(使用两个进程分别在不同端口启动driver),appium log没有错误,pycharm也一直转转转卡在那不去执行find element, 所以还是还原到使用import multiprocessing
最终解决方案如下:
1. mac裡面的python都刪乾淨
2. 用pyenv裝python 3.5.2
3. 執行multi process case script
4. 把該裝的selenium, Pillow, requests裝一裝
5. 最後一步降级appium-python-client : pip install appium-python-client==0.25 (这个是重点,可以忽略其他步骤直接降级版本,这里是因为需要才重装, 当然笔者local的0.31版本也可以的,就是最新版(0.43)有问题)
6. 成功!
multiprocessing--强大Manage
'''''' multiprocessing--强大Manage '''''' from multiprocessing import Manager, Process def worker(dt,lt): for i in range(10): key = "args" + str(i) dt[key] = i*i lt += [x for x in range(10)] # 两个列表相加 if __name__ == ''__main__'': manager = Manager() dt = manager.dict() lt = manager.list() p = Process(target=worker,args=(dt,lt)) p.start() p.join(timeout=3) #等待子进程执行完 print(dt) print(lt)
multiprocessing.Manager()dict()setdefault()是否损坏?
其后期且可能是愚蠢的部门提出:
>>> import multiprocessing
>>> mgr = multiprocessing.Manager()
>>> d = mgr.dict()
>>> d.setdefault('foo',[]).append({'bar': 'baz'})
>>> print d.items()
[('foo',[])] <-- Where did the dict go?
鉴于:
>>> e = mgr.dict()
>>> e['foo'] = [{'bar': 'baz'}]
>>> print e.items()
[('foo',[{'bar': 'baz'}])]
版:
>>> sys.version
'2.7.2+ (default,Jan 20 2012,23:05:38) \n[GCC 4.6.2]'
虫子还是臭虫?
编辑:更多相同,在python 3.2上:
>>> sys.version
'3.2.2rc1 (default,Aug 14 2011,21:09:07) \n[GCC 4.6.1]'
>>> e['foo'] = [{'bar': 'baz'}]
>>> print(e.items())
[('foo',[{'bar': 'baz'}])]
>>> id(type(e['foo']))
137341152
>>> id(type([]))
137341152
>>> e['foo'].append({'asdf': 'fdsa'})
>>> print(e.items())
[('foo',[{'bar': 'baz'}])]
字典代理中的列表如何不包含其他元素?
multiprocessing.Manager()。dict()。setdefault()是否损坏?
其后期且可能是愚蠢的部门提出:
>>> import multiprocessing>>> mgr = multiprocessing.Manager()>>> d = mgr.dict()>>> d.setdefault(''foo'', []).append({''bar'': ''baz''})>>> print d.items()[(''foo'', [])] <-- Where did the dict go?
鉴于:
>>> e = mgr.dict()>>> e[''foo''] = [{''bar'': ''baz''}]>>> print e.items()[(''foo'', [{''bar'': ''baz''}])]
版:
>>> sys.version''2.7.2+ (default, Jan 20 2012, 23:05:38) \n[GCC 4.6.2]''
虫子还是臭虫?
编辑:更多相同,在python 3.2上:
>>> sys.version''3.2.2rc1 (default, Aug 14 2011, 21:09:07) \n[GCC 4.6.1]''>>> e[''foo''] = [{''bar'': ''baz''}]>>> print(e.items())[(''foo'', [{''bar'': ''baz''}])]>>> id(type(e[''foo'']))137341152>>> id(type([]))137341152>>> e[''foo''].append({''asdf'': ''fdsa''})>>> print(e.items())[(''foo'', [{''bar'': ''baz''}])]
字典代理中的列表如何不包含其他元素?
答案1
小编典典这是一些非常有趣的行为,我不确定它是如何工作的,但我会弄清楚为什么是这样的行为。
首先,请注意multiprocessing.Manager().dict()
不是dict
,而是一个DictProxy
对象:
>>> d = multiprocessing.Manager().dict()>>> d<DictProxy object, typeid ''dict'' at 0x7fa2bbe8ea50>
DictProxy
该类的目的是为您提供一个dict
可以在进程之间共享的安全对象,这意味着它必须在常规dict
功能之上实现一些锁定。
显然,此处实现的一部分是不允许您直接访问嵌套在内的可变对象DictProxy
,因为如果允许,您将能够以绕过所有使DictProxy
安全使用的锁定的方式修改共享对象。
这是一些您无法访问可变对象的证据,这与发生的情况类似setdefault()
:
>>> d[''foo''] = []>>> foo = d[''foo'']>>> id(d[''foo''])140336914055536>>> id(foo)140336914056184
使用普通字典,您会期望d[''foo'']
并foo
指向同一个列表对象,而对一个字典的修改会修改另一个。如您所见,DictProxy
由于多处理模块强加了额外的过程安全性要求,因此该类并非如此。
编辑:
以下来自多处理文档的注释阐明了我在上面试图说的内容:
注意:
对dict和list代理中的可变值或项的修改不会通过管理器传播,因为代理无法知道何时修改其值或项。要修改此类项目,可以将修改后的对象重新分配给容器代理:
# create a list proxy and append a mutable object (a dictionary)lproxy = manager.list()lproxy.append({})# now mutate the dictionaryd = lproxy[0]d[''a''] = 1d[''b''] = 2# at this point, the changes to d are not yet synced, but by# reassigning the dictionary, the proxy is notified of the changelproxy[0] = d
根据上述信息,以下是您如何重写原始代码以与一起使用的方法DictProxy
:
# d.setdefault(''foo'', []).append({''bar'': ''baz''})d[''foo''] = d.get(''foo'', []) + [{''bar'': ''baz''}]
正如Edward Loper在评论中建议的那样,对以上代码进行了编辑,以 get()
代替 setdefault()
。
今天关于使用multiprocessing.Manager.list而不是真实列表会使计算耗时的分享就到这里,希望大家有所收获,若想了解更多关于Appium - multiprocessing.pool.MaybeEncodingError-【 “Can’t pickle local object ‘PoolManager.__init...、multiprocessing--强大Manage、multiprocessing.Manager()dict()setdefault()是否损坏?、multiprocessing.Manager()。dict()。setdefault()是否损坏?等相关知识,可以在本站进行查询。
本文标签: