问题

问题

问题

pytesseract.image_to_string()当我通过supervisordd运行脚本时花费了太多时间,但是当直接在shell中运行时(在同一服务器上并与supervisor脚本同时运行)几乎立即执行。
除了花费太多时间之外,这些进程还显示出较高的 CPU 使用率。

pytesseract.image_to_string()通过 Supervisord 运行所需的时间:~30s 通过 Bash 运行
所需的时间pytesseract.image_to_string():0.1s

仅当有大量进程pytesseract.image_to_string()正在通过supervisord 执行(大约22 个实例)运行时,才会出现此问题。如果我减少实例数量(减少到 10 个左右),通过supervisord 执行的脚本也会顺利运行。

系统信息

操作系统:Ubuntu 18.04.2 LTS(仿生)
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(或者我知道这个问题的根源不是)

我相当确定这不是 Supervisord 的问题。

当我从 ssh shell 运行一个实例时,函数 ( pytesseract.image_to_string()) 执行得很顺利(即只需要 0.1 秒),而有 10 个实例通过 Supervisord 运行。
当我从新的 ssh shell 启动另一个实例时,这两个实例(从 ssh 启动的实例)在大多数情况下都运行顺利。
当我从新的 ssh shell 启动另一个实例时,所有三个实例都开始阻塞,需要大约 10 秒才能执行该函数。随着我通过 shell 添加更多实例,这个时间不断增加。

所以即使使用 shell 也可以复制该问题。

更多信息

我运行了该程序,strace -T -f但我无法弄清楚到底是什么导致了时间峰值。

对于需要 1s 的函数调用

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'

它修复了线程开销。

相关内容