首页 > 解决方案 > 使用多线程python将数据写入文件

问题描述

我正在调用函数视觉来处理图像,我想处理大量图像并将数据写入文件。我正在使用多线程并运行 4 个线程并将不同的图像名列表传递给每个线程,但是当我将数据写入文件时,它被覆盖并仅显示一个线程的结果。如何更快地处理这些图像并将来自函数的数据写入文件中。这是我的视觉功能。

def vision(filelist):
    from google.cloud import vision
    from google.cloud.vision import types
    os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = r'Logo Detection-ecc10ae26b70.json'
    global lck
    global df
    global dff
    lck.acquire()
    for i in range(len(onlyfiles)):
        imagepath=batch_folder+"\\"+onlyfiles[i]
        with io.open(onlyfiles[i], 'rb') as image_file:
            content = image_file.read()
            logolist=[]
            labellist=[]
            objectlist=[]
            image = vision.types.Image(content=content)
            response = client.logo_detection(image=image)
            logos = response.logo_annotations
            response = client.label_detection(image=image)
            labels = response.label_annotations
            objects = client.object_localization(image=image).localized_object_annotations

            for logo in logos:
                logolist.append(logo.description)
            for label in labels:
                labellist.append(label.description)
            for obj in objects:
                objectlist.append(obj.name)
            logolist2.append(logolist)
            labellist2.append(labellist)
            objectlist2.append(objectlist)
            dff=[]  
            lck.acquire()
            dff = pd.DataFrame(list(zip(onlyfiles,logolist2,labellist2,objectlist2)),columns =['filename', 'logo','label','object'])
            df.append(dff,ignore_index=True)
            lck.release()


    df.to_csv(csvadd, index=False) 

############image reading and divding data for threads#################
batch_folder='D:\\Projects\\VAT\\fakedetection\\keyframe\\ffmpeg-4.2.1-win64-static\\video'
onlyfiles = fnmatch.filter(os.listdir(batch_folder), '*.jpg') 
countofimage=len(onlyfiles)
division=int(countofimage/4)
index1=[0,division]
index2=[division+1,division+division]
index3=[division+division+1,division+division+division]
index4=[division+division+division+1,division+division+division+division]
threadfile1=onlyfiles[index1[0]:index1[1]]
threadfile2=onlyfiles[index2[0]:index2[1]]
threadfile3=onlyfiles[index3[0]:index3[1]]
threadfile4=onlyfiles[index4[0]:index4[1]]   

t1 = threading.Thread(target=vision, args=(threadfile1,)) 
t2 = threading.Thread(target=vision, args=(threadfile2,)) 
t3 = threading.Thread(target=vision, args=(threadfile3,)) 
t4 = threading.Thread(target=vision, args=(threadfile4,)) 

# starting thread 1 
t1.start() 
# starting thread 2 
t2.start() 
t3.start()
t4.start()

# wait until thread 1 is completely executed 
t1.join() 
# wait until thread 2 is completely executed 
t2.join() 
t3.join()
t4.join()
# both threads completely executed 
print("Done!") 

我厌倦了锁和全局df,但输出并非来自文件中的所有线程。如果此代码需要任何改进以更快地处理,请建议并帮助将来自线程的数据写入文件代码工作正常没有错误。我不仅仅是得到正确的输出

标签: pythonmultithreading

解决方案


并发处理文件是多线程中的一个标准问题。如果处理不当,就会像您的情况一样出现丢失更新问题等问题。

使用锁是确保所有更新都出现在文件中的一种方法。但是,如果您使用锁,其他线程将不得不等到锁被释放后才能写入文件。根据每个线程锁定的持续时间,在最坏的情况下,程序最终可能会像单线程应用程序一样执行。

我解决问题的方法根本不依赖于锁:您是否可以先将不同线程的输出写入不同的文件,然后再合并输出文件?这样,您就不必担心丢失更新。


推荐阅读