Python多线程文件去重

2024-05-04 08:38
文章标签 多线程 python

本文主要是介绍Python多线程文件去重,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

注:本文基于python2.7.5

之前已经使用python写过文件去重的脚本(Windows下使用python删除重复图片),但是文件多了脚本运行比较慢,因此改进一下,使用多线程感受一下效果。

思路还是不变,通过比较文件的MD5值确定是否是同一文件,相似图片暂不考虑,有机会研究一下。

代码如下:

#-*-  coding: UTF-8  -*-import threading
import os
import sys
import hashlib
import time
import shutildef thread_run(name):threadLockForPrint.acquire()print("starting: Thread" + str(name)) #如果不使用锁,打印可能出现串行的情况,串口也是全局资源threadLockForPrint.release()threadLockForPhoto.acquire()while len(photoes) > 0:photo = photoes.pop()threadLockForPhoto.release()photomd5 = getmd5(photo)threadLockForMD5.acquire()if photomd5 not in photoMd5List:photoMd5List.append(photomd5)threadLockForMD5.release()else:threadLockForMD5.release()threadLockForIdentical.acquire()identicalPhotoes.append(photo)threadLockForIdentical.release()threadLockForPhoto.acquire()threadLockForPhoto.release()def getmd5(file):if not os.path.isfile(file):  return  f = open(file,'rb')md5 = hashlib.md5()md5.update(f.read())f.close()return md5.hexdigest()         def getFiles(targetDir):allfiles = []for path,dir,filelist in os.walk(targetDir):for filename in filelist:allfiles.append(os.path.join(path, filename))return allfilesif __name__ == "__main__":dirname = sys.argv[1]if len(sys.argv) == 3:identicalDir = sys.argv[2]else:identicalDir = ""threadLockForPhoto = threading.Lock()threadLockForMD5 = threading.Lock()threadLockForIdentical = threading.Lock()threadLockForPrint = threading.Lock()global identicalPhotoesidenticalPhotoes = []global photoMd5ListphotoMd5List = []global photoesphotoes = getFiles(dirname)threads = []start = time.time()for i in range(5): #create 5 threadst = threading.Thread(target=thread_run, args=(i+1,))t.start()threads.append(t)for thread in threads:thread.join()end = time.time()last = end - startprint("There are " + str(len(identicalPhotoes)) + " identical photo(es)")if os.path.exists(identicalDir):for i in identicalPhotoes:shutil.move(i, identicalDir)print(i.decode('gbk'))print("main thread exit: lasts for " + str(last) + "s")

脚本接收两个入参,一个是需要去重的文件目录(必须),另一个是存放重复文件的目录(可选)。如果没有指定存放重复文件的目录,则不移动重复文件,仅打印重复文件数量。

主要是使用threading这个模块实现,通过继承threading.Thread,并重写__init__和run函数,就能将自己需要运行的操作定义在线程中了。这里我们定义两个线程,然后调用线程的start()函数,之后就会调用我们定义的run函数,执行我们希望的操作。为防止主线程在子线程前结束,调用join()函数,等待所有子线程结束后,主线程再退出。

因为有多个线程在运行,我们不得不考虑同步的问题,不然数据就会出现不一致了。考虑到我们有三个全局变量,所有照片的列表,非重复照片的MD5值列表,以及重复图片列表,因此我们定义三个线程锁,当然也可以只定义一个锁,但是锁的粒度过大的话就很影响线程的执行效率,因此我们细化锁的粒度,这样线程间对全局资源的操作更为灵活。

加锁的操作在对列表读取、添加前,操作完成后,立马释放该锁,以便其他线程可以持有该锁。

这篇关于Python多线程文件去重的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/958786

相关文章

Zen of Python -Python之禅

在浏览Python官方文档时无意发现了这个彩蛋,只需在终端中import this The Zen of Python, by Tim PetersBeautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than compli

Python内置函数oct()详解

Python中的oct()函数是一个内置函数,用于将一个整数转换成它的八进制字符串表示。 函数定义 oct()函数的基本语法如下: oct(x) x:一个整数。 函数返回x的八进制表示,以字符串形式。 基本用法 将整数转换为八进制 number = 64print(oct(number)) # 输出: '0o100' 转换负整数 number = -64print(o

Python筑基之旅-溯源及发展

目录 一、Python的起源 二、Python的版本更替及变化 三、Python的优缺点 四、Python的发展方向 五、Python之禅 六、推荐专栏/主页: 1、Python函数之旅:Functions 2、Python算法之旅:Algorithms 3、个人主页:https://myelsa1024.blog.csdn.net/ ​​​​​​​ 一、Python

Python专题:十六、异常处理(2)

异常的预判和防护 import randomnum = random.randint(1, 100) # 获得一个随机数is_done = False # 是否猜中的标记count = 0 # 玩家猜了几次while not is_done:guess = int(input('请输入一个[1, 100]的整数:'))if guess == num:is_done = Trueelif

理解 Python 中的 `super()` 与 `__init__()` 方法

在 Python 的面向对象编程中,super() 函数和 __init__() 方法是两个非常重要的概念。它们在类的继承和初始化过程中扮演着关键的角色。本文将深入探讨这两个概念的工作原理,并通过示例代码来展示它们的使用。 基本原理 __init__() 方法 __init__() 是一个特殊的方法,也称为类的构造器。当你创建一个类的新实例时,Python 会自动调用这个方法。它通常用于初始

python 合并 pdf

from pypdf import PdfMergerpdfs = ['file1.pdf', 'file2.pdf', 'file3.pdf', 'file4.pdf']merger = PdfMerger()for pdf in pdfs:merger.append(pdf)merger.write("result.pdf")merger.close() 参考 https://stack

Python——IO编程

IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。 比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后新浪服务器把网页发过来,

python 脚本压缩文件linux 正常,windows 文件夹/文件名称 被加上了上级文件夹名

场景: php 在调用python 脚本,进行文件压缩(因为php的压缩大文件总是超时),linux/mac 环境文件/文件夹名压缩前后一致,windows 压缩后 文件/文件夹名被改变为 上级 文件夹+原名 原因: windows 和 mac、linux 文件路径的分隔符 不一样 解决: 使用php 自带的分隔符常量DIRECTORY_SEPARATOR,该常量会根据 不同系统,变化

Python简易图书管理系统重构

在本篇课文中,我们将使用Python语言结合MySQL数据库,从零开始构建一个简单的图书管理系统。该系统旨在帮助图书馆管理员轻松管理图书的借阅、归还以及查询图书信息等日常操作。我们将分步介绍需求分析、数据库设计、环境搭建、功能实现等关键环节,并提供详细的源代码示例。 #### **一、需求分析** 图书管理系统的核心功能包括: - 图书录入:允许管理员添加新书到系统。 - 图书查询:提供按书名

python开发的学习路线

I. 基础知识学习 A. Python基础语法         变量和数据类型 学习如何定义变量,理解并使用不同的数据类型(整数、浮点数、字符串、布尔值等)。 掌握数字类型的转换和操作。 熟悉字符串的基本操作,如拼接、切片、替换和查找。                                                                控制流程 掌握条件语句