我认为threading
,您应该在multiprocessing
Python解决方案中使用模块,而不是使用模块。Python线程可能会违反GIL;如果您只是要运行多个Python进程,那么GIL并不是问题。
我认为,对于您正在执行的工作进程,池只是您想要的。默认情况下,池将默认为系统处理器中的每个核心使用一个进程。只需.map()
使用要检查的文件名列表和执行检查的函数来调用该方法。
http://docs.python.org/library/multiprocessing.html
如果这不比您的threading
实现快,那么我不认为GIL是您的问题。
编辑:好的,我正在添加一个可运行的Python程序。这使用工作进程池来打开每个文件并在每个文件中搜索模式。当工作人员找到匹配的文件名时,它只是将其打印(到标准输出),因此您可以将此脚本的输出重定向到文件中,并获得文件列表。
编辑:我认为这是一个稍微容易阅读的版本,更易于理解。
我计时了一下,在计算机上的/ usr / include中搜索文件。它会在大约半秒钟内完成搜索。使用find
管道传输xargs
来运行尽可能少的grep
进程,大约需要0.05秒,大约是原来的10倍。但是我讨厌必须使用巴洛克风格的怪异语言find
才能正常工作,而且我喜欢Python版本。也许在非常大的目录中,差异会更小,因为Python半秒的一部分一定是启动时间。对于大多数用途而言,也许半秒就足够了!
import multiprocessing as mp
import os
import re
import sys
from stat import S_ISREG
# uncomment these if you really want a hard-coded $HOME/patterns file
#home = os.environ.get('HOME')
#patterns_file = os.path.join(home, 'patterns')
target = sys.argv[1]
size_limit = int(sys.argv[2])
assert size_limit >= 0
patterns_file = sys.argv[3]
# build s_pat as string like: (?:foo|bar|baz)
# This will match any of the sub-patterns foo, bar, or baz
# but the '?:' means Python won't bother to build a "match group".
with open(patterns_file) as f:
s_pat = r'(?:{})'.format('|'.join(line.strip() for line in f))
# pre-compile pattern for speed
pat = re.compile(s_pat)
def walk_files(topdir):
"""yield up full pathname for each file in tree under topdir"""
for dirpath, dirnames, filenames in os.walk(topdir):
for fname in filenames:
pathname = os.path.join(dirpath, fname)
yield pathname
def files_to_search(topdir):
"""yield up full pathname for only files we want to search"""
for fname in walk_files(topdir):
try:
# if it is a regular file and big enough, we want to search it
sr = os.stat(fname)
if S_ISREG(sr.st_mode) and sr.st_size >= size_limit:
yield fname
except OSError:
pass
def worker_search_fn(fname):
with open(fname, 'rt') as f:
# read one line at a time from file
for line in f:
if re.search(pat, line):
# found a match! print filename to stdout
print(fname)
# stop reading file; just return
return
mp.Pool().map(worker_search_fn, files_to_search(target))