您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

并行文件匹配,Python

并行文件匹配,Python

我认为threading,您应该在multiprocessingPython解决方案中使用模块,而不是使用模块。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))
python 2022/1/1 18:29:28 有193人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶