如何在Python中将字节对象正确传递给新的Thread?

时间:2015-12-23 18:44:50

标签: python multithreading

我正在尝试读取1GB文件,将其分成4MB文件,然后使用多个线程单独上传。但是,我不认为我正确地传递了“块”对象。我怀疑这一行可能不正确:

threading.Thread(target=UploadFile, args=[filename, chunk]).start()

在将其作为参数传递之前,是否需要复制“chunk”?我担心的是“chunk”在这个例子中不是线程安全的,因此,上传的块与源数据不一致。

以下是完整的方法:

def ChunkAndUpload(inputFilename):
    global runningThreadCount
    maxThreads = 10
    chunkSize = 1024*1024*4
    index = 0
    with open(inputFilename, "rb") as f:
        while True:
            chunk = f.read(chunkSize)
            if not chunk: break
            filename = str(index) + ".dat"
            while (True):
                if (runningThreadCount<maxThreads):
                    runningThreadCount += 1
                    threading.Thread(target=UploadFile, args=[filename, chunk]).start()
                    break
                else:
                    sleep(.1)
            index+=1

谢谢!

2 个答案:

答案 0 :(得分:4)

bytes是一个不可变类型(就像str一样)。不可变类型不受竞争条件的影响(除非您可以使用对完全不同的对象的引用来完全替换共享名称)。

一旦args=[filename, chunk],您就制作了一个新的list,其中“恰巧”包含与bytes相同的chunk的引用;从那一刻起,chunk可以重新分配,无论list是否成功发布,它都不会影响Thread的内容。

答案 1 :(得分:3)

即使通过引用新线程传递参数(因此更改为块将显示在另一个线程中),您的代码也不会到块字节数组,它只需要参考每次从f.read到新的字节对象。因此,您似乎应该是安全的,但如果上传速度足够慢,您可能会立即将整个文件读入内存。