簡體   English   中英

設置多線程 python 3

[英]Setting up multithreading python 3

我有一個 python 腳本,它獲取輸入文件列表並在這些文件上運行 cmd。 列表中平均大約有 6,000 個文件。 (因批次而異)。 這個基於 cmd 的程序平均每個輸入文件需要大約 1-2 分鍾才能完成,因此最終處理整個列表大約需要幾天時間。

我希望使用多線程在我的幾個處理器之間拆分列表,以便可以串聯處理列表並最終更快!

輸入再次是文件列表,並且 output 被寫入與輸入文件相同的目錄,但為 inputx_output.csv

我似乎無法讓多線程工作。 這是當前沒有多線程的代碼段。 每次我查看一些多線程引用時,它似乎都不能很好地適應我的代碼。

這是一個段,不包含單獨運行所需的所有引用/輸入。

import shutil as sh
Input_File ='c:/Users/James_Mann1/Desktop/TestBench'

import os
try:
    os.chdir(Input_File)
except:
    catch = 1
try:
    sh.rmtree("Cas-Out")
except:
    catch = 1
try:
    os.mkdir("Cas-Out")
except:
    catch = 1 
#print(os.getcwd())
os.chdir("Cas-OffInput")
path = os.getcwd()
Input_Casoff = os.listdir(path)
src = Input_File + "/cas-offinder.exe"
dst = Input_File + "/Cas-OffInput/cas-offinder.exe"
sh.copyfile(src, dst)
for value in Input_Casoff:
    subprocess.call("cas-offinder " + value + " G0 " + " " + value + "out.txt")
    #os.system("cas-offinder " + value + " G0 " + " " + value + "out.txt")

我不確定從哪里開始? 我似乎找不到寫這篇文章的好參考。 我要做的就是獲取列表條目並在它們上串聯運行 cmd,因此該過程完成得更快。 output 由 cmd 生成,因此無需捕獲任何內容。

編輯,我能夠解決最初的問題。 發布在下面...現在我想返回一個計數,它告訴我還剩多少。

import os
from queue import Queue
from threading import Thread
from time import sleep
import shutil as sh
import time
#%%
import shutil as sh
Input_File ='c:/Users/James_Mann1/Desktop/TestBench'

import os
try:
    os.chdir(Input_File)
except:
    catch = 1
try:
    sh.rmtree("Cas-Out")
except:
    catch = 1
try:
    os.mkdir("Cas-Out")
except:
    catch = 1
#print(os.getcwd())
os.chdir("Cas-OffInput")
path = os.getcwd()
Input_Casoff = os.listdir(path)
src = Input_File + "/cas-offinder.exe"
dst = Input_File + "/Cas-OffInput/cas-offinder.exe"
sh.copyfile(src, dst)

Task_Count = len(Input_Casoff)

from multiprocessing import Pool

def Cas_off(x):
    os.system("cas-offinder " + x + " G0 " + " " + x + "out.txt")
    #print(x)
    return x

if __name__ == '__main__':
    with Pool(8) as p:
        print(p.map(Cas_off, Input_Casoff))

關於實施獲取剩余條目的方法有什么建議嗎? 所以

x/4000 已完成或正在處理 x/4000。

謝謝!

一種方法是使用mpi4py ,即 MPI(消息傳遞接口)的 python 版本,它使您能夠進行並行計算。 MPI 是一個相當大的庫,使您能夠在多個處理器上運行程序,甚至可以在這些處理器之間進行通信。

在 MAC 上,我使用 brew 安裝了它:

brew install open-mpi

然后,您可以使用 pip 安裝 mpi4py:

pip3 install mpi4py

那么你的代碼結構應該是這樣的:

from mpi4py import MPI

comm = MPI.COMM_WORLD # MPI communicator
size = comm.Get_size() # Number of processors
rank = comm.Get_rank() # Rank of the processor

# Input and output file names
nb_files = 10
input_files = [f'input_file_{i}.txt' for i in range(nb_files)]
output_files = [f'output_file_{i}.txt' for i in range(nb_files)]

# Loop on all files to process
for i in range(len(input_files)):
    # The current processor will process only files at indexes
    # equal to his rank modulo the total number of processors
    # else it will skip the file.
    if (i%size==rank):
        # Here processor rank must:
        # - read file input_files[i]
        # - process the data
        # - write file output_files[i]
        print(f'CPU{rank} transforms "{input_files[i]}" into "{output_files[i]}".') # dummy code

您可以使用以下命令執行代碼(將 4 替換為所需的 CPU 數量,並將 script.py 替換為 python 程序文件的名稱):

mpiexec -n 4 python3 script.py

Output:

% mpiexec -n 4 python3 script.py
CPU3 transforms "input_file_3.txt" into "output_file_3.txt".
CPU3 transforms "input_file_7.txt" into "output_file_7.txt".
CPU1 transforms "input_file_1.txt" into "output_file_1.txt".
CPU1 transforms "input_file_5.txt" into "output_file_5.txt".
CPU1 transforms "input_file_9.txt" into "output_file_9.txt".
CPU0 transforms "input_file_0.txt" into "output_file_0.txt".
CPU0 transforms "input_file_4.txt" into "output_file_4.txt".
CPU0 transforms "input_file_8.txt" into "output_file_8.txt".
CPU2 transforms "input_file_2.txt" into "output_file_2.txt".
CPU2 transforms "input_file_6.txt" into "output_file_6.txt".

小心避免多個處理器處理同一個文件以避免沖突(所有文件名應該不同)。 同樣,MPI 是一個非常大的庫,您可以想象使用它添加通信(例如每分鍾)以減少所有處理器之間完成的文件數量。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM