Python多处理:丢失计数池.连接()?

2024-10-03 06:25:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图解决这个问题,我存储了给定长度的子串的位置和计数。由于字符串可能很长(基因组序列),所以我尝试使用多个过程来加速。当程序运行时,存储对象的变量似乎在线程结束后丢失所有信息。在

import numpy
import multiprocessing
from multiprocessing.managers import BaseManager, DictProxy
from collections import defaultdict, namedtuple, Counter
from functools import partial
import ctypes as c

class MyManager(BaseManager):
        pass

MyManager.register('defaultdict', defaultdict, DictProxy)

def gc_count(seq):
        return int(100 * ((seq.upper().count('G') + seq.upper().count('C') + 0.0) / len(seq)))

def getreads(length, table, counts, genome):
        genome_len = len(genome)
        for start in range(0,genome_len): 
                gc = gc_count(genome[start:start+length])
                table[ (length, gc) ].append( (start) )
                counts[length,gc] +=1

if __name__ == "__main__":
    g = 'ACTACGACTACGACTACGCATCAGCACATACGCATACGCATCAACGACTACGCATACGACCATCAGATCACGACATCAGCATCAGCATCACAGCATCAGCATCAGCACTACAGCATCAGCATCAGCATCAG'
    genome_len = len(g)

    mgr = MyManager()
    mgr.start()
    m = mgr.defaultdict(list)
    mp_arr = multiprocessing.Array(c.c_double, 10*101)
    arr = numpy.frombuffer(mp_arr.get_obj())
    count = arr.reshape(10,101)

    pool = multiprocessing.Pool(9)
    partial_getreads = partial(getreads, table=m, counts=count, genome=g)
    pool.map(partial_getreads, range(1, 10))
    pool.close()
    pool.join()

    for i in range(1, 10):
            for j in range(0,101):
                    print count[i,j]
    for i in range(1, 10):
            for j in  range(0,101):
                    print len(m[(i,j)])

结尾的循环只会为count中的每个元素输出0.0,而{}中每个列表的0,所以不知何故我失去了所有的计数。如果我在getreads(...)函数中打印计数,我可以看到值正在增加。相反,在getreads(...)len(m[(i,j)])中打印len(table[ (length, gc) ])只会得到0。在


Tags: inimportforgenomelencountrangemultiprocessing
1条回答
网友
1楼 · 发布于 2024-10-03 06:25:03

你也可以把你的问题描述成一个map-reduce问题,这样就可以避免在多个进程之间共享数据(我想这会加快计算速度)。您只需要从函数(map)返回结果表和计数,并合并所有进程的结果(reduce)。在

回到你最初的问题。。。在

Managers的底部有一个关于 对dict和list中可变值或项目的修改。基本上,你 需要将修改后的对象重新分配给容器代理。在

l = table[ (length, gc) ]
l.append( (start) )
table[ (length, gc) ] = l

还有一篇关于combining pool map with Array的Stackoverflow帖子。在

考虑到这两个因素,你可以做一些类似的事情:

^{pr2}$

相关问题 更多 >