Python 多个子流程需要很多时间才能完成
我有一个使用Python 多个子流程需要很多时间才能完成,python,ubuntu,subprocess,tesseract,popen,Python,Ubuntu,Subprocess,Tesseract,Popen,我有一个使用子流程模块的Popen运行的进程: result = subprocess.Popen(['tesseract','mypic.png','myop']) st = time() while result.poll() is None: sleep(0.001) en = time() print('Took :'+str(en-st)) 其结果是: Took :0.44703030586242676 这里,调用tesseract处理图像mypic.png(附件),并将
子流程
模块的Popen
运行的进程:
result = subprocess.Popen(['tesseract','mypic.png','myop'])
st = time()
while result.poll() is None:
sleep(0.001)
en = time()
print('Took :'+str(en-st))
其结果是:
Took :0.44703030586242676
这里,调用tesseract
处理图像mypic.png
(附件),并将OCR结果输出到myop.txt
现在,我希望代表(或参见)在多个进程上实现这一点,因此代码如下:
lst = []
for i in range(4):
lst.append(subprocess.Popen(['tesseract','mypic.png','myop'+str(i)]))
i=0
l = len(lst)
val = 0
while(val!=(1<<l)-1):
if(lst[i].poll() is None):
print('Waiting for :'+str(i))
sleep(0.01)
else:
temp = val
val = val or (1<<(i))
if(val!=temp):
print('Completed for :'+temp)
i = (i+1) %l
lst=[]
对于范围(4)中的i:
追加(subprocess.Popen(['tesseract','mypic.png','myop'+str(i)])
i=0
l=len(lst)
val=0
而(val!=(1Per)(我的重点是):
在处理一个页面时,Tesseract 4最多还使用四个CPU线程,因此对于单个页面,它将比Tesseract 3更快
如果您的计算机只有两个CPU内核,那么运行四个线程将显著降低速度,最好使用一个线程,或者最多使用两个线程!使用一个线程可以消除多线程的计算开销,也是通过运行一个线程来处理大量图像的最佳解决方案每个CPU核心的seract进程
使用环境变量OMP\u THREAD\u LIMIT设置最大线程数
要禁用多线程,请使用OMP_THREAD_LIMIT=1
因此,如果您希望同时运行多个tesseract进程,您可能希望减少(或尝试)OMP_线程限制。
最佳值取决于计算机可以同时支持的线程数
例如,在我的机器上:
import subprocess
import time
import os
t = time.perf_counter()
tasks = [('mypic.png', 'myop{}'.format(i)) for i in range(4)]
procs = [subprocess.Popen(['tesseract', infile, outfile], env={'OMP_THREAD_LIMIT':'1'})
for infile, outfile in tasks]
for proc in procs:
proc.wait()
print('{} s'.format(time.perf_counter()-t))
完成时间为0.220秒,而相同的代码没有env={'OMP\u THREAD\u LIMIT':'1'}
通常需要3.1-5.1秒,运行之间有很大的差异
要使代码正常工作,请使用,而不是:
请注意,循环仍然会迭代数千次,主要是在lst[i].poll()返回None
时,
也因为i=(i+1)%l
可以多次重新访问同一个值。
如果一次迭代需要0.001s,那么6121次迭代将需要6.121s。因此,while
循环非常复杂,速度也不是很快。您可能想看看如何轻松并行运行多个子进程。太棒了!谢谢!如果您想知道确切的命令:OMP\u THREAD\u LIMIT=1 tesseract
…或者,从在应用程序可能调用的任何命令上执行以下操作:import os
然后os.environ['OMP\u THREAD\u LIMIT']='1'
。
val = val | (1 << (i))
import time
import subprocess
lst = []
for i in range(4):
lst.append(subprocess.Popen(['tesseract', 'mypic.png', 'myop'+str(i)]))
i = 0
l = len(lst)
val = 0
counter = 0
while(val != (1 << l)-1):
if(lst[i].poll() is None):
time.sleep(0.001)
else:
temp = val
val = val | (1 << (i))
if(val != temp):
print('Completed for : {}'.format(i))
i = (i+1) % l
counter += 1
print('{} iterations'.format(counter))
Completed for : 1
Completed for : 2
Completed for : 3
Completed for : 0
6121 iterations