我不确定这是否可能(希望如此)。我有一个数据集,在使用defaultdict的进程中运行。DefaultDict有一个特性,如果你搜索某个东西,而它不在字典中,它就会被添加(在我的例子中,我搜索它们被添加的值,然后我在后面搜索这些值,如果它们在dict中,那么我将值从默认的false设置为True)。工作非常容易,没有问题,但我开始得到错误的结果,一旦我尝试多处理这个(真正的数据/进程是相当大的,加上我有多核硬件,为什么不使用它,对吗?)。以下是我的结果(使用多处理的表的大小似乎总是在变化,有时没有多处理的情况下是相同的,但通常会稍小一些):
size of Table(with multiprocesing) is: 398
total number of true(with multiprocesing) is 0
size of Table(without multiprocesing) is 402
total number of true(without multiprocessing) is 250
不管怎样,这里有一些函数代码。顶部是多处理的代码,底部是没有多处理的代码(我想出了如何使defaultdict与所有新进程共享,但仍然不起作用):
^{pr2}$我希望有解决办法。在过去的两周里,我试着把它运行到一个数据库中,但是对于非常大的数据集来说太慢了。上面的进程处理内存中的所有内容(但是仍然需要几个小时来运行我的测试数据,这就是为什么我要在它上使用多核)。在
使用标准的
defaultdict
可以很容易地复制defaultdict
的行为。在这种情况下,我觉得您可以简单地替换test
中的这一行:用这条线:
^{pr2}$在费心自定义管理器对象之前,看看是否可以让这些代码使用标准字典。在
但实际上,
i
的每个值似乎都将存储处理i + 1
的循环可以访问的值。这意味着每个循环的结果取决于前一个循环,因此异步方法可能会产生错误。在要对此进行扩展,请尝试以下代码:
输出如下:
如您所见,如果您调用}计算开始之前,}计算已经读取了该键之后。(实际上,尽管在上面的例子中表的长度相同,但是您会注意到
p.wait()
,则执行顺序是顺序的;如果不调用,则执行顺序就乱了。而且因为它是无序的,您会注意到,i = 1
和{i = 0
的所有计算都完成了。这有时可能意味着i = 0
计算会写入i = 1
使用的键,但只有在{order
列表的长度是不同的。因此,发生了一些不同的事情,即使它不影响最终结果。)我修了一些东西
我从函数调用中删除了T,这会杀死您定义为的进程变量经理.defaultdict(布尔)
编辑:实际上,我刚刚意识到,T是全局的,因为没有def main,我把T恢复到函数调用中。很抱歉。:)
编辑2:我还在同步之后添加了p.wait()。我想这可能是你看到水滴的地方。我注意到了同样的滴液,但加上p.wait似乎已经阻止了孩子们滴下的水。在
编辑3:将p.wait()更改为p.get(timeout=5)
您只需要传递函数参数,而不需要传递全局变量。 此外,在循环中,T一旦完成,其结果是:
T=defaultdict(,{(7,3):真,(90,0):假。。。等})
所以我改变了for循环来获取键value。在
^{pr2}$我做了一个快速检查,我怀疑,子进程正在创建它自己的T版本。您需要设置一个全局变量,并让管理器更新该变量。在
我在test函数中添加了这个,以查看id T是什么:
地址:T 823f50 地址:T 955550 地址:T 955bd0
所以当孩子们完成任务时,家长们永远不会得到更新。在
我将使用它来设置一个全局或进程共享dict
相关问题 更多 >
编程相关推荐