Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多个子流程需要很多时间才能完成_Python_Ubuntu_Subprocess_Tesseract_Popen - Fatal编程技术网

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