Многопоточность не использует полную емкость процессора / памяти / диска - PullRequest
0 голосов
/ 06 апреля 2020

Мой Python код предназначен для извлечения информации из XML файлов и загрузки ее в базу данных. Эти файлы называются номерами 11582.xml, 5300593.xml, et c. и у меня есть около 1 миллиона файлов.

Я создал код, и он работает нормально. Я столкнулся с проблемой, что код не занимает полную емкость процессора / памяти / диска. Мой процессор должен использовать максимум 20%.

Я спросил здесь и в других местах и ​​обнаружил, что мне нужно использовать многопоточность, чтобы использовать полную емкость. Поэтому я должен изменить свой сценарий для принятия многопоточности. Я сделал это, но по-прежнему не работает до максимума.

Что я сделал не так? и как это исправить?

Мой код:

import pymssql
import pyodbc
import pandas as pd
import thread
import glob
import xml.etree.ElementTree as ET

conn = pyodbc.connect('Driver={SQL Server};'
                      'Server=Server123;'
                      'Database=NLP;'
                      'Trusted_Connection=yes;')


cursor = conn.cursor()

def ExtractData(ThreadName):
    for file in glob.glob("H:\\datas_Output\\xmldata\\" & ThreadName & "*.xmi"):

        filename = file[24:-8]
        tree = ET.parse(file)
        root = tree.getroot()

        for Tag in ['Kitkat', 'Snickers', 'Bounty']:
            iTag = '{textsem.ecore}' + Tag
            for country in root.findall(iTag):
                XMIID = country.get('{XMI}id')
                sofa = country.get('sofa')
                cursor.execute("INSERT INTO Tags (filename,tag,xmiid,sofa) VALUES (?,?,?,?)", filename, Tag, XMIID, sofa)



try:
   thread.start_new_thread( ExtractData, ("1") )
   thread.start_new_thread( ExtractData, ("2") )
except:
   print("Error: unable to start thread")

conn.commit()

Ответы [ 2 ]

1 голос
/ 06 апреля 2020

Почему бы не создать список файлов и затем обработать их с помощью пула?

import multiprocessing

def ExtractData(file):
    filename = file[24:-8]
    tree = ET.parse(file)
    root = tree.getroot()

    for Tag in ['Kitkat', 'Snickers', 'Bounty']:
        iTag = '{textsem.ecore}' + Tag
        for country in root.findall(iTag):
            XMIID = country.get('{XMI}id')
            sofa = country.get('sofa')
            cursor.execute("INSERT INTO Tags (filename,tag,xmiid,sofa) VALUES (?,?,?,?)", filename, Tag, XMIID, sofa)

# if there are millions of files, you might want an iterator
filename_iterator = glob.iglob("H:/datas_Output/xmldata/", recursive=True)

with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
    results = pool.map(ExtractData, filename_iterator)


0 голосов
/ 06 апреля 2020

Python многопоточность не является "реальной". Во-первых, есть «Глобальная блокировка интерпретатора» (GIL), которая позволяет одновременно запускать py только одному потоку. Кроме того, потоки python не используют независимые ядра реальных процессоров. Основным преимуществом является то, что один поток может быть заблокирован на внешних операциях ввода / вывода; другие потоки могут что-то делать.

Однако в других средах, таких как JVM (Java, Kotlin et c.), поддерживаются реальные потоки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...