Kiedy analizujesz pliki PDF partiami, dlaczego każdy proces powinien sam otwierać plik?

Zadania wieloprocesowe powinny przekazywać parametry możliwe do serializacji i umożliwiać każdej jednostce roboczej niezależne otwieranie dokumentu, zamiast udostępniać obiekty dokumentu lub strony. Poniższe testy podzieliły pokrycie na segmenty i niezależnie otwarte funkcje robocze; aby zachować przenośność i możliwość kontroli, przykład jest serializowany i nie traktuje go jako wieloprocesowego testu wydajności.

Podczas przetwarzania plików PDF wsadowo wiele osób będzie chciało, aby wiele procesów korzystało z tego samego obiektu dokumentu, myśląc, że oszczędzi to kłopotów. W rzeczywistości obiekty Document i Page są powiązane z procesem, który je utworzył, a użycie ich w różnych procesach może powodować problemy. Ten artykuł jest odpowiedni dla programistów, którzy muszą używać wielu procesów do dzielenia stron PDF i wyodrębniania tekstu partiami. Po przeczytaniu będziesz wiedział jakie parametry przekazać procesowi potomnemu, w jaki sposób proces potomny powinien otworzyć plik, a w jakich przypadkach konieczny jest powrót do pojedynczego procesu lub wprowadzenie OCR.

W przykładzie zastosowano próbki syntetyczne, a kod konstruuje dane wejściowe w pamięci. Weryfikuje przetwarzanie segmentowanego pokrycia i niezależnie otwieranych plików i nie stanowi gwarancji wszystkich rzeczywistych plików ani wydajności produktu. Przed przystąpieniem do przetwarzania ważnych dokumentów prosimy o zachowanie oryginałów i zapoznanie się z nimi zgodnie z poniższymi granicami i punktami akceptacji.

Podczas przetwarzania pliku PDF partiami, w jaki sposób każdy proces powinien otwierać plik? Wniosek w jednym zdaniu

Zadania wieloprocesowe powinny przekazywać parametry możliwe do serializacji, a każda jednostka pracy powinna otwierać dokument niezależnie, zamiast współużytkować obiekty Document lub Page.

twoja sytuacjaZalecane praktykipowód
Wymaga wieloprocesowego przetwarzania wsadowego plików PDFPrzekaż parametry możliwe do serializacji, takie jak nazwa pliku, zakres numerów stron itp., a każdy proces potomny sam wywoła pymupdf.open()Document przechowuje wskaźnik podstawowej struktury C i uchwyt pliku i nie można go bezpiecznie przekazywać między procesami
Chcesz bezpośrednio przekazać obiekty Document lub PageNiezalecanePrzerwie z powodu niepowodzenia wybierania lub wyjątku z powodu nieprawidłowego wskaźnika
Wiele procesów chce pisać do tego samego pliku wyjściowegoKażdy proces zapisuje niezależne pliki tymczasowe, które są łączone przez proces głównyW przypadku braku synchronizacji zawartość może zostać rozłożona lub uszkodzona
Wymagane jest powiązanie między stronami, np. łączenie tabel między stronami i indeksowanie pełnotekstoweWróć do przetwarzania jednoprocesowego lub zaprojektuj wyspecjalizowaną strategię agregacji fragmentarycznejProcesy są od siebie odizolowane i nie mogą mieć wspólnego kontekstu

Dlaczego nie można przekazać obiektu Document do procesu potomnego?

Główną przyczyną jest to, że Document wewnętrznie przechowuje wskaźniki i uchwyty plików do bazowych struktur C. Zasoby te są powiązane z przestrzenią pamięci procesu, który je utworzył. Po przekazaniu przez procesy wskaźniki tracą ważność, a inny proces nie może uzyskać legalnego dostępu do uchwytów.

Prawidłowe podejście polega na przekazywaniu tylko parametrów możliwych do serializacji, takich jak nazwa pliku (łańcuch znaków) i zakres stron, i umożliwieniu każdemu procesowi potomnemu wywołania pymupdf.open() niezależnie w jego własnej przestrzeni pamięci. To nie jest kompromis w zakresie wydajności. Proces potomny jest niezależnym bytem sam w sobie i tak czy inaczej wymaga własnej instancji dokumentu, aby bezpiecznie wykonywać operacje pobierania lub renderowania.

Przykład samodzielnej kompozycji

Zobacz listę importu kodu poniżej, aby poznać zależności. Kod konstruuje dane wejściowe w pamięci, ułatwiając ich odtworzenie w izolowanym środowisku.

import pymupdf
def partition(total, chunk):
    if type(chunk) is not int or chunk <= 0:
        raise ValueError("positive chunk required")
    return [(start, min(start + chunk, total)) for start in range(0, total, chunk)]
def worker(raw, start, end):
    with pymupdf.open(stream=raw, filetype="pdf") as doc:
        return [(i, doc[i].get_text()) for i in range(start, end)]
with pymupdf.open() as doc:
    for index in range(5):
        doc.new_page().insert_text((50, 50), f"Page {index}")
    raw = doc.tobytes()
tasks = partition(5, 2)
assert tasks == [(0, 2), (2, 4), (4, 5)]
results = [item for start, end in tasks for item in worker(raw, start, end)]
assert [i for i, text in results] == list(range(5))
assert all(f"Page {i}" in text for i, text in results)
assert partition(0, 2) == []

Zależności i instrukcje obsługi

W tym przykładzie chunksize z pool.map używa wartości domyślnej 1, która jest odpowiednia w scenariuszach, w których szczegółowość pojedynczego zadania jest duża. Jeśli stron jest wiele, a przetwarzanie pojedynczej strony jest szybkie, wartość chunksize można zwiększyć, aby zmniejszyć narzut związany z komunikacją między procesami. Jednak ten przykład skupia się na bezpieczeństwie, a nie dostrajaniu wydajności.

Przykład syntezy: prawidłowe dane wejściowe i granica zagrożenia

Poprawne dane: Przekaż krotkę (segment_id, filename, start_page, end_page). gdzie filename jest ścieżką ciągu, a start_page i end_page są liczbami całkowitymi. Po otrzymaniu parametrów proces potomny samodzielnie otwiera plik, przetwarza określony zakres numerów stron i zwraca listę wyników.

Granica zagrożenia:

  • Numer strony poza zakresem: jeśli zakres numerów stron to (18, 25), ale dokument faktycznie ma tylko 20 stron, gdy proces potomny uzyska dostęp do strony 21, zostanie uruchomiony indeks poza zakresem.
  • Bezpośrednie przekazanie Document: zostanie przerwane w przypadku niepowodzenia marynowania.
  • Wiele procesów zapisuje ten sam plik: bez mechanizmu synchronizacji zawartość wyjściowa zostanie przeplatana lub uszkodzona.

Rozwiązaniem jest natychmiastowe sprawdzenie, czy zakres numerów stron przekracza doc.page_count na wejściu procesu potomnego i umożliwienie wszystkim operacjom we/wy korzystania z niezależnych ścieżek docelowych lub buforów pamięci. Obiekty, których nie można serializować, należy wykluczyć z parametrów zadania na etapie projektowania, zamiast polegać na wyjątkach wychwytujących w czasie wykonywania.

📊 Porównanie rdzeni

WymiaryPrzekaż obiekt dokumentuPrzekaż parametry możliwe do serializacji (zalecane)
Czy można go przekazywać między procesami?Nie, nie zawiedzie przez ogórkiTak, ciągi i liczby całkowite mogą być przekazywane bezpośrednio
Własność zasobów podstawowychZwiązany z procesem, który ją stworzyłKażdy proces potomny otwiera pliki niezależnie
Zachowanie błędnepickle.PicklingError lub procesy potomne cicho się zawieszająNumery stron przekraczające granice można zweryfikować przy wejściu

Kryteria akceptacji i granice ręcznej oceny

Obserwuj to zjawiskoMożliwe przyczynyDecyzja o zajęciu się tą sprawą
pickle.PicklingError lub cichy crash procesu potomnegoPrzekazywanie obiektów nieserializowalnych, takich jak dokument/stronaPrzekazywane są tylko podstawowe typy, takie jak ciągi ciągów, liczby całkowite i krotki
Niektóre numery stron zwracają puste ciągi znakówLiczba stron przekracza rzeczywistą liczbę stron lub strony są czysto obrazami bez warstw tekstowychSprawdź granice numer strony; Czyste oznaczanie stron obrazowych wymaga OCR, czyli oczekiwanego zachowania
Zawartość pliku wyjściowego jest nieprawidłowaWiele procesów zapisuje się do tego samego plikuKażdy proces zapisuje niezależny plik tymczasowy, a główny proces się łączy
Zużycie pamięci rośnie liniowo wraz z liczbą procesówKażdy proces ładuje pełną dokumentacjęZaakceptuj ten koszt; Jeśli dokument jest zbyt duży, przejdź na strumieniowanie stron

Ten tryb nie nadaje się do zadań wymagających kontekstowego powiązania między stronami, takich jak łączenie tabel międzystronnych czy budowanie indeksu pełnego tekstu, ponieważ procesy są od siebie odizolowane. W przypadku takich potrzeb powinieneś wrócić do przetwarzania w jednym procesie lub zaprojektować dedykowaną strategię agregacji blokowej.

Co więcej, przykład ten tylko weryfikuje "bezpieczną równoległą ekstrakcję" i nie gwarantuje efektów end-to-end. Jakość tekstu, dokładność kodowania i zachowanie formatowania nadal wymagają ręcznej kontroli próbkowania. Szczególną uwagę należy zwrócić na zeskanowane pliki PDF, ponieważ ekstrakcja tekstu zwykłego może całkowicie zawiódć, w takim przypadku należy wprowadzić OCR.

Jeśli ......

Jeśli musisz wyodrębnić tekst PDF w trybie batch parallel

Zadania są podzielone według przedziału liczby stron, przekazując jedynie podstawowe typy, takie jak nazwy plików i numery stron, a każdy proces potomny otwiera pliki niezależnie.

Jeśli twoje zadanie wymaga łączenia wyników między stronami

Priorytetowo traktuj zwracanie pojedynczych procesów lub projektowanie strategii agregacji blokowej; nie wymuszaj równoległości.

Jeśli masz do czynienia ze skanowanymi PDF-ami

Najpierw sprawdź, czy istnieje warstwa tekstowa. Jeśli nie, przed przeprowadzeniem inspekcji należy dodać do procesu krok OCR.

❓ Najczęściej zadawane pytania (FAQ)

1. Dlaczego obiekt Dokument nie może być przekazany bezpośrednio do procesu potomnego?

Document wewnętrznie przechowuje wskaźniki i uchwyty plików wskazujące na podstawową strukturę C. Te zasoby są powiązane z procesem, który je stworzył. Przekazywanie między procesami staje się nieważne i przerywane, jeśli pickle się nie powiedzie.

2. Dlaczego procesy potomne otwierają każdy własny plik?

Jako niezależne podmioty, procesy potomne potrzebują własnych instancji dokumentów, aby bezpiecznie przeprowadzić ekstrakcję lub renderowanie. To właściwe podejście, a nie wada wydajności.

3. Co zrobić, jeśli liczba stron przekracza określony zakres?

Przy wpisie podprocesu natychmiast sprawdź, czy numer strony przekracza doc.page_count; nie kontynuuj dostępu do niej, jeśli przekroczy granicę.

4. Czy wiele procesów może zapisać ten sam plik wyjściowy jednocześnie?

Nie polecam. Bez mechanizmów synchronizacji zawartość może być przeplatana lub uszkodzona. Każdy proces powinien zapisać niezależny plik tymczasowy, a następnie scalać go przez główny proces.

📝 Podsumowanie

W wieloprocesowych PDF-ach bezpieczniejszym rozwiązaniem jest przekazywanie parametrów serializowalnych i umożliwienie każdemu podprocesowi samodzielnego otwierania plików. Zadania powiązania między stronami i zeskanowane pliki muszą być oceniane oddzielnie, a ostateczna ręczna weryfikacja próbkowania jest nadal przeprowadzana na podstawie rzeczywistych próbek.

Doświadczenie teraz: Prześlij dokument, aby zacząć tłumaczyć, zachowując oryginalne formatowanie

Używaj list kontrolnych do tłumaczenia dokumentów

Najpierw dokładnie sprawdź kolejność stron, lokalizację źródła i integralność tekstu, a następnie przekaż tę samą próbkę odczuliwości do procesu tłumaczeniowego. Po tłumaczeniu nadal konieczne jest sprawdzenie, czy tytuł, główny tekst i podpisy prawidłowo się zgadzają; nie wystarczy oceniać tylko na podstawie płynności tekstu.

OmniDoc (wpis produktu) oferuje portal tłumaczeń dokumentów w wielu formatach, a jego oficjalna strona internetowa wprowadza OCR, słowniki oraz funkcje tłumaczenia dwujęzycznego. Dla zespołów, które chcą zacząć bezpośrednio od plików, jest to ścieżka warta oceny na podstawie rzeczywistych próbek. Prosimy o użycie zanonimizowanego pliku, który uznałeś, aby przesłać i zweryfikować wyniki za pomocą listy kontrolnej opisanej w tym artykule. Nie oznacza to, że OmniDoc korzysta z bibliotek open-source ani wspomnianych tu algorytmów wewnętrznych, ani nie zastępują testów wydajności produktu.

Baza interfejsu referencyjnego: Dokument PyMuPDF

Zaktualizowano 2026-11-13