
질문
pytesseract.image_to_string()
Supervisordd를 통해 스크립트를 실행하면 시간이 너무 오래 걸리지만 셸에서 직접 실행하면(동일한 서버에서 감독자 스크립트와 동시에) 거의 즉시 실행됩니다.
시간이 너무 많이 걸릴 뿐만 아니라 이러한 프로세스는 CPU 사용량도 높습니다.
pytesseract.image_to_string()
Supervisord를 통해 실행하는 데 필요한 시간: ~30s Bash를 통해 실행하는 데
필요한 시간 pytesseract.image_to_string()
: 0.1s
pytesseract.image_to_string()
이 문제는 감독자 실행을 통해 실행되는 프로세스 수가 많은 경우(약 22개 인스턴스)에만 발생합니다 . 인스턴스 수를 10개 정도로 줄이면 Supervisord를 통해 실행되는 스크립트도 원활하게 실행됩니다.
시스템 메시지
운영 체제: Ubuntu 18.04.2 LTS(Bionic)
Supervisord: 버전 3.3.1
Tesseract: 버전 4.0.0-beta.1
Python: 버전 3.6
PyTesseract: 버전 0.2.5
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 127357
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 8096
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 127357
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
더 많은 정보가 필요하면 알려주시기 바랍니다.
편집 1(또는 이 문제의 원인이 아닌 것으로 알고 있음)
나는 이것이 감독자의 문제가 아니라고 확신합니다.
SSH 셸에서 하나의 인스턴스를 실행하면 Supervisord를 통해 10개의 인스턴스가 실행되는 동안 함수( pytesseract.image_to_string()
)가 원활하게 실행됩니다(즉, 0.1초만 소요).
새 SSH 셸에서 다른 인스턴스를 시작하면 두 인스턴스(ssh에서 시작된 인스턴스)가 대부분 원활하게 실행됩니다.
새 SSH 셸에서 다른 인스턴스를 시작하면 세 인스턴스 모두 차단을 시작하고 함수를 실행하는 데 약 10초가 걸립니다. 셸을 통해 더 많은 인스턴스를 추가하면 이 시간이 계속 늘어납니다.
따라서 쉘을 사용해도 문제를 재현할 수 있습니다.
추가 정보
프로그램을 실행했지만 strace -T -f
시간이 급증하는 원인이 정확히 무엇인지 알 수 없습니다.
1초가 걸리는 함수 호출의 경우
Top 10 system calls sorted by time taken
1.504530 [pid 29921] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 30166
0.503915 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.503472 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.500524 [pid 29933] <... select resumed> ) = 0 (Timeout)
0.500515 [pid 29933] <... select resumed> ) = 0 (Timeout)
0.500514 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.500512 [pid 29933] <... select resumed> ) = 0 (Timeout)
0.069869 [pid 30169] <... futex resumed> ) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
0.035989 [pid 30167] <... futex resumed> ) = 0
0.016002 [pid 30168] <... futex resumed> ) = 0
9초가 걸리는 함수 호출의 경우
Top 10 system calls sorted by time taken
9.795787 [pid 29921] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 30106
0.515960 [pid 29933] <... select resumed> ) = 0 (Timeout)
0.511955 [pid 29933] <... select resumed> ) = 0 (Timeout)
0.507979 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.507968 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.505257 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.503988 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.503978 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.503975 [pid 29932] <... select resumed> ) = 0 (Timeout)
0.503974 [pid 29932] <... select resumed> ) = 0 (Timeout)
답변1
tesseract에서 다중 처리를 비활성화하면 문제가 해결되었습니다. 이는 OMP_THREAD_LIMIT=1
환경 설정을 통해 수행할 수 있습니다.
바라보다https://github.com/tesseract-ocr/tesseract/issues/898#issuecomment-315202167
답변2
Python 프로세스에서:
import os
os.environ['OMP_THREAD_LIMIT'] = '1'
스레드 오버헤드를 수정합니다.