鱼C论坛

 找回密码
 立即注册
查看: 1853|回复: 4

多线程复制文件,在线程启动时出现了问题

[复制链接]
发表于 2020-7-31 19:31:51 | 显示全部楼层 |阅读模式
30鱼币
import os
import hashlib
from threading import Thread, Lock
import time

ORIGIN_PATH = r'F:\Python\拷贝\test1'
TARGET_PATH = r'F:\Python\拷贝\test2'

all_filename = os.listdir(ORIGIN_PATH)
# print(all_filename)
th_ls = []
lock = Lock()
count = 0
ls = []

pro = []

CHUNKSIZE = 4096    # 每次读取文件的字节数
def copy_hashFile(filename,path=None, write_filename=None):
    '''
    对文件做hash
    '''
    def myCopy():
        # 以二进制的形式在文件末尾追加写入
        with open(path + os.sep + write_filename, 'ab') as f:
            f.write(chunk)
    h = hashlib.sha256()
    with open(filename, 'rb') as f:
        while True:
            chunk = f.read(CHUNKSIZE)
            if not chunk:   # 当读文件到结尾处时,跳出循环
                pro.append(filename)
                break
            h.update(chunk)
            if path:
                # 开始循环写入文件
                myCopy()
    return h.hexdigest()    # 得到文件最终的hash值

def main():
    global count
    while True:
        if not all_filename:
            os._exit(0)
        with lock:
            filename = all_filename.pop()
        # print(filename)
        # 在目标文件夹下创建一个空文件
        # print(ORIGIN_PATH + os.sep + filename)
        with open(TARGET_PATH + os.sep + filename, 'w'):
            pass
        # 获得原文件hash值并将其复制到目标文件夹下
        hash_number1 = copy_hashFile(ORIGIN_PATH + os.sep + filename, TARGET_PATH, filename)
        # 获得复制后的hash值
        hash_number2 = copy_hashFile(TARGET_PATH + os.sep + filename)
        
        # 比较hash值
        if hash_number1 == hash_number2:
            with lock:
                count += 1
            print(str(count) + '  ' + filename + '文件复制成功')
        else:
            with lock:
                count += 1
                ls.append(filename)
            print(str(count) + '  ' + filename + '文件复制失败')



for _ in range(20):
    th = Thread(target=main)
    th_ls.append(th)

# 不清楚为什么
# 只有sleep 1秒以上后才不会出错
for each in th_ls:
    each.start()
    time.sleep(5)


while True:
    # print(not all_filename)
    # time.sleep(1.5)
    if not all_filename:
        for each in th_ls:
            each.join()

代码如上,我之前在复制测试文件的时候,一直有几个文件无法复制,在添加了sleep(1)后才成功,后来复制更多更大的文件后,复制的成功率随着sleep的时间增加而增加,这是为什么呢?
求大佬

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-1 00:08:09 | 显示全部楼层
发现了问题所在了,是那个os._exit(0)导致的,这行代码还会导致线程无法回收,改成break就行了。
唉,事实证明Python的多线程IO还是比不过单线程,单线程的代码比这快多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-1 06:34:10 | 显示全部楼层
读写文件这种 磁盘 io 用多线程是会快一些的,慢了说明哪里用的不对。

点评

我很赞同!: 5.0
我很赞同!: 5
同意  发表于 2020-8-1 08:55
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-3 18:09:10 | 显示全部楼层
对啊,这一般都用多线程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-19 14:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表