鱼C论坛

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

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

[复制链接]
最佳答案
0 
发表于 2020-7-31 19:31:51 | 显示全部楼层 |阅读模式
30鱼币
  1. import os
  2. import hashlib
  3. from threading import Thread, Lock
  4. import time

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

  7. all_filename = os.listdir(ORIGIN_PATH)
  8. # print(all_filename)
  9. th_ls = []
  10. lock = Lock()
  11. count = 0
  12. ls = []

  13. pro = []

  14. CHUNKSIZE = 4096    # 每次读取文件的字节数
  15. def copy_hashFile(filename,path=None, write_filename=None):
  16.     '''
  17.     对文件做hash
  18.     '''
  19.     def myCopy():
  20.         # 以二进制的形式在文件末尾追加写入
  21.         with open(path + os.sep + write_filename, 'ab') as f:
  22.             f.write(chunk)
  23.     h = hashlib.sha256()
  24.     with open(filename, 'rb') as f:
  25.         while True:
  26.             chunk = f.read(CHUNKSIZE)
  27.             if not chunk:   # 当读文件到结尾处时,跳出循环
  28.                 pro.append(filename)
  29.                 break
  30.             h.update(chunk)
  31.             if path:
  32.                 # 开始循环写入文件
  33.                 myCopy()
  34.     return h.hexdigest()    # 得到文件最终的hash值

  35. def main():
  36.     global count
  37.     while True:
  38.         if not all_filename:
  39.             os._exit(0)
  40.         with lock:
  41.             filename = all_filename.pop()
  42.         # print(filename)
  43.         # 在目标文件夹下创建一个空文件
  44.         # print(ORIGIN_PATH + os.sep + filename)
  45.         with open(TARGET_PATH + os.sep + filename, 'w'):
  46.             pass
  47.         # 获得原文件hash值并将其复制到目标文件夹下
  48.         hash_number1 = copy_hashFile(ORIGIN_PATH + os.sep + filename, TARGET_PATH, filename)
  49.         # 获得复制后的hash值
  50.         hash_number2 = copy_hashFile(TARGET_PATH + os.sep + filename)
  51.         
  52.         # 比较hash值
  53.         if hash_number1 == hash_number2:
  54.             with lock:
  55.                 count += 1
  56.             print(str(count) + '  ' + filename + '文件复制成功')
  57.         else:
  58.             with lock:
  59.                 count += 1
  60.                 ls.append(filename)
  61.             print(str(count) + '  ' + filename + '文件复制失败')



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

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


  70. while True:
  71.     # print(not all_filename)
  72.     # time.sleep(1.5)
  73.     if not all_filename:
  74.         for each in th_ls:
  75.             each.join()
复制代码


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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
最佳答案
0 
 楼主| 发表于 2020-8-1 00:08:09 | 显示全部楼层
发现了问题所在了,是那个os._exit(0)导致的,这行代码还会导致线程无法回收,改成break就行了。
唉,事实证明Python的多线程IO还是比不过单线程,单线程的代码比这快多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
最佳答案
266 
发表于 2020-8-1 06:34:10 | 显示全部楼层
读写文件这种 磁盘 io 用多线程是会快一些的,慢了说明哪里用的不对。

点评

我很赞同!: 5.0
我很赞同!: 5
同意  发表于 2020-8-1 08:55
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
最佳答案
21 
发表于 2020-8-3 18:09:10 | 显示全部楼层
对啊,这一般都用多线程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

小甲鱼强烈推荐上一条 /1 下一条

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

GMT+8, 2020-8-12 11:18

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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