小编Fab*_*aze的帖子

多处理中的共享内存

我有三个大清单.首先包含bitarrays(模块bitarray 0.8.0),另外两个包含整数数组.

l1=[bitarray 1, bitarray 2, ... ,bitarray n]
l2=[array 1, array 2, ... , array n]
l3=[array 1, array 2, ... , array n]
Run Code Online (Sandbox Code Playgroud)

这些数据结构需要相当多的RAM(总共约16GB).

如果我使用以下方式启动12个子流程:

multiprocessing.Process(target=someFunction, args=(l1,l2,l3))
Run Code Online (Sandbox Code Playgroud)

这是否意味着将为每个子流程复制l1,l2和l3,或者子流程是否会共享这些列表?或者更直接,我会使用16GB或192GB的RAM吗?

someFunction将从这些列表中读取一些值,然后根据读取的值执行一些计算.结果将返回到父进程.someIunction不会修改列表l1,l2和l3.

因此,我认为子流程不需要也不会复制这些巨大的列表,而只是与父级共享它们.这意味着由于linux下的写时复制方法,该程序将占用16GB的RAM(无论我启动多少个子进程)?我是正确的还是我错过了会导致列表被复制的内容?

编辑:在阅读了关于这个主题的更多内容后,我仍然感到困惑.一方面,Linux使用copy-on-write,这意味着不会复制任何数据.另一方面,访问该对象将改变其重新计数(我仍然不确定为什么以及这意味着什么).即便如此,是否会复制整个对象?

例如,如果我定义someFunction如下:

def someFunction(list1, list2, list3):
    i=random.randint(0,99999)
    print list1[i], list2[i], list3[i]
Run Code Online (Sandbox Code Playgroud)

是否使用此函数意味着将为每个子流程完全复制l1,l2和l3?

有没有办法检查这个?

EDIT2在子流程运行的同时读取更多内容并监视系统的总内存使用情况后,似乎确实为每个子流程复制了整个对象.它似乎是因为引用计数.

在我的程序中实际上不需要l1,l2和l3的引用计数.这是因为l1,l2和l3将保留在内存中(未更改),直到父进程退出.在此之前,不需要释放这些列表使用的内存.事实上,我确信引用计数将保持在0以上(对于这些列表和这些列表中的每个对象),直到程序退出.

所以现在问题变成了,我怎样才能确保不会将对象复制到每个子进程?我可以禁用这些列表和这些列表中的每个对象的引用计数吗?

EDIT3只是一个额外的说明.子进程并不需要修改l1,l2l3或在这些列表中的任何对象.子进程只需要能够引用其中一些对象,而不会导致为每个子进程复制内存.

python shared-memory multiprocessing large-data

56
推荐指数
4
解决办法
8万
查看次数

Python禁用某些对象的引用计数

这个问题来自这里.

我有三个包含python对象(l1,l2l3)的大型列表.这些列表是在程序启动时创建的,它们总共需要16GB的RAM.该程序将专门用于linux.

创建后,我不需要以任何方式或形式修改这些列表或这些列表中的对象.它们必须保留在内存中,直到程序退出.

我在我的程序中使用os.fork()和多处理模块来生成多个子进程(当前最多20个).这些子流程中的每一个都需要能够读取三个列表(l1,l2l3).

我的程序在其他方面工作正常并且非常快.但是我遇到内存消耗问题.由于Linux上的写时复制方法,我希望每个子进程都可以使用这三个列表而不将它们复制到内存中.但是情况并非如此,因为引用任何这些列表中的任何对象都会增加相关的引用计数,从而导致整个内存页面被复制.

所以我的问题是:

我可以禁用引用计数l1,l2以及l3这些列表中的所有对象吗?基本上将整个对象(包括诸如引用计数之类的元数据)设置为只读,以便在任何情况下都不会被修改(我认为,这将允许我利用写入时复制).

目前我担心我被迫转移到另一种编程语言来完成这项任务,因为我目前不需要的"功能"(引用计数),但仍然强加给我并导致不必要的问题.

python refcounting

10
推荐指数
1
解决办法
815
查看次数

Python多处理内存使用情况

我写了一个程序,可以总结如下:

def loadHugeData():
    #load it
    return data

def processHugeData(data, res_queue):
    for item in data:
        #process it
        res_queue.put(result)
    res_queue.put("END")

def writeOutput(outFile, res_queue):
    with open(outFile, 'w') as f
        res=res_queue.get()
        while res!='END':
            f.write(res)
            res=res_queue.get()

res_queue = multiprocessing.Queue()

if __name__ == '__main__':
    data=loadHugeData()
    p = multiprocessing.Process(target=writeOutput, args=(outFile, res_queue))
    p.start()
    processHugeData(data, res_queue)
    p.join()
Run Code Online (Sandbox Code Playgroud)

真正的代码(特别是writeOutput())要复杂得多.writeOutput()仅使用它作为参数的这些值(意味着它不引用data)

基本上它将一个巨大的数据集加载到内存中并对其进行处理.输出的写入被委托给一个子进程(它实际写入多个文件,这需要花费很多时间).因此,每次处理一个数据项时,它都会通过res_queue发送到子进程,res_queue会根据需要将结果写入文件.

子进程不需要以loadHugeData()任何方式访问,读取或修改加载的数据.子流程只需要使用主流程发送它的内容res_queue.这引出了我的问题和疑问.

在我看来,子流程将它放在庞大数据集的副本上(当检查内存使用情况时top).这是真的?如果是这样,我怎么能避免id(基本上使用双内存)?

我使用的是Python 2.6,程序在linux上运行.

python linux memory-management multiprocessing

10
推荐指数
1
解决办法
1万
查看次数

Python subprocess.call() 为每个 stdout 和 stderr 行添加前缀

我正在使用 python 运行一些 shell 脚本、RScript、python 程序等。这些程序可能会运行很长时间,并且可能会向 stdout 和 stderr 输出大量(日志记录)信息。我正在使用以下(Python 2.6)代码,它运行良好:

stdoutFile=open('stdout.txt', 'a')
stderrFile=open('stderr.txt', 'a')
subprocess.call(SHELL_COMMAND, shell=True, stdout=stdoutFile, stderr=stderrFile)
stdoutFile.close()
stderrFile.close()
Run Code Online (Sandbox Code Playgroud)

这主要是记录到文件的信息,并且该信息可以在很长一段时间内生成。因此我想知道是否可以在每一行前面加上日期和时间?

例如,如果我当前要记录:

Started
Part A done
Part B done
Finished
Run Code Online (Sandbox Code Playgroud)

那么我希望它是:

[2012-12-18 10:44:23] Started
[2012-12-18 12:26:23] Part A done
[2012-12-18 14:01:56] Part B done
[2012-12-18 22:59:01] Finished
Run Code Online (Sandbox Code Playgroud)

注意:修改我运行的程序不是一个选项,因为这个 python 代码有点像这些程序的包装器。

python logging datetime subprocess stdout

6
推荐指数
1
解决办法
2496
查看次数

SQL在不同的行上选择每个选定列的值

我有一个包含数百行和数十W列的表:

Column1 | Column2_W | Column3_W | ColumnX_W
  123   |     A     |     B     |    x
  223   |     A     |    NULL   |  NULL
Run Code Online (Sandbox Code Playgroud)

如何选择它以使输出为:

Column1 | W 
  123   | A
  123   | B
  123   | x
  223   | A
Run Code Online (Sandbox Code Playgroud)

编辑:我很清楚我正在使用可怕的数据库"设计".不幸的是我无法改变它.这个问题实际上是我今天提出的一个更大问题的一部分.我明天会尝试给定的想法

sql select

4
推荐指数
1
解决办法
3362
查看次数

Python随机从大文件N行(没有重复的行)

我需要使用python从大型txt文件中获取N行.这些文件基本上是制表符分隔的表.我的任务有以下限制:

  • 这些文件可能包含标题(某些文件包含多行标题).
  • 标题需要以相同的顺序出现在输出中.
  • 每行只能使用一次.
  • 目前最大的文件大约是150GB(大约6,000,000行).
  • 行在文件中的长度大致相同,但可能在不同文件之间有所不同.
  • 我通常会随机抽取5000行(我可能需要多达1 000 000行)

目前我已经编写了以下代码:

inputSize=os.path.getsize(options.input)
usedPositions=[] #Start positions of the lines already in output

with open(options.input) as input:
    with open(options.output, 'w') as output:

        #Handling of header lines
        for i in range(int(options.header)):
            output.write(input.readline())
            usedPositions.append(input.tell())

        # Find and write all random lines, except last
        for j in range(int(args[0])):
            input.seek(random.randrange(inputSize)) # Seek to random position in file (probably middle of line)
            input.readline() # Read the line (probably incomplete). Next input.readline() results in a complete line.
            while input.tell() …
Run Code Online (Sandbox Code Playgroud)

python random line readline large-files

3
推荐指数
1
解决办法
3365
查看次数