在Python中动态加载Threadable类

时间:2014-10-11 01:38:45

标签: python multithreading

我发布了一个问题here,我得到了解决。

我的新问题与最后的代码有关,这些代码遍历目录中的模块并以动态方式加载它们:

modules = pkgutil.iter_modules(path=[os.path.join(path,'scrapers')])
for loader, mod_name, ispkg in modules:
    # Ensure that module isn't already loaded, and that it isn't the parent class
    if (mod_name not in sys.modules) and (mod_name != "Scrape_BASE"):
        # Import module
        loaded_mod = __import__('scrapers.'+mod_name, fromlist=[mod_name])
        # Load class from imported module. Make sure the module and the class are named the same
        class_name = mod_name
        loaded_class = getattr(loaded_mod, class_name)
        # only instantiate subclasses of Scrape_BASE
        if(issubclass(loaded_class,Scrape_BASE.Scrape_BASE)): 
            # Create an instance of the class and run it
            instance = loaded_class()
            instance.start()
            instance.join()
            text = instance.GetText()

在大多数课程中,我正在从网站上阅读PDF,抓取内容并设置随后由GetText()返回的文本。

在某些情况下,PDF太大,我最终会遇到分段错误。有没有办法监视线程,使它们在3分钟左右后超时?有没有人建议我如何实现这个?

1 个答案:

答案 0 :(得分:0)

正确这样做的方法是更改​​那些你没有向我们展示过的类中的代码,这样它们就不会永远运行。如果可能,你绝对应该这样做。如果您想要超时的是“从网站上阅读PDF”,那几乎可以肯定。

但有时,这是不可能的;有时你只是在调用一些没有超时的C函数。那么,你怎么办呢?

好吧,线程不能被打断。所以你需要使用流程。 multiprocessing.Processthreading.Thread非常相似,只是它在子进程中运行代码而不是同一进程中的线程。

这意味着您无法与工作人员共享任何全局数据而不明确,但这通常是良好的事物。但是,它确实意味着输入数据(在这种情况下似乎不是任何东西)和输出(似乎是一个大字符串)必须是可选择的,并且显式地通过队列传递。这很容易做到;请阅读Exchanging objects between processes部分了解详情。

虽然我们正在努力,但您可能需要考虑重新考虑您的设计,以便根据任务而不是线程进行思考。如果您要下载200个PDF,那么您真的不需要200个线程;你想要8个或12个线程,所有线程都可以处理200个工作队列。 multiprocessing模块支持进程池,但您可能会发现concurrent.futures更适合此过程。 multiprocessing.Poolconcurrent.futures.ProcessPoolExecutor都允许你传递一个函数和一些参数,然后等待结果,而不必担心调度或队列或其他任何事情。