python - 使用多线程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,但输出并非来自文件中的所有线程。如果此代码需要任何改进以更快地处理,请建议并帮助将来自线程的数据写入文件代码工作正常没有错误。我不仅仅是得到正确的输出
解决方案
并发处理文件是多线程中的一个标准问题。如果处理不当,就会像您的情况一样出现丢失更新问题等问题。
使用锁是确保所有更新都出现在文件中的一种方法。但是,如果您使用锁,其他线程将不得不等到锁被释放后才能写入文件。根据每个线程锁定的持续时间,在最坏的情况下,程序最终可能会像单线程应用程序一样执行。
我解决问题的方法根本不依赖于锁:您是否可以先将不同线程的输出写入不同的文件,然后再合并输出文件?这样,您就不必担心丢失更新。
推荐阅读
- sql - 查询存在和不存在
- linux - 当多个进程监听同一个端口时,操作系统负载如何平衡它们之间的流量?
- python - Pandas:根据其他两列更改其中一列中的值的最有效方法
- firefox - Firefox 中的 Flex 项目对齐问题
- flutter - 为什么 VS Code 中的 Flutter 指导线断了
- python - 如何解决 camelot-py read_pdf 错误“找不到 EOF 标记”?
- php - 我的 php 代码中不断出现“非法字符串偏移”,我该如何解决?
- ubuntu - 如何从源代码编译 ps 命令?
- javascript - Javascript - 如何将项目分配到嵌套数组中,如发牌?
- json - json.Marshal 与 Encoder.Encode