我发布了一个问题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分钟左右后超时?有没有人建议我如何实现这个?
答案 0 :(得分:0)
正确这样做的方法是更改那些你没有向我们展示过的类中的代码,这样它们就不会永远运行。如果可能,你绝对应该这样做。如果您想要超时的是“从网站上阅读PDF”,那几乎可以肯定。
但有时,这是不可能的;有时你只是在调用一些没有超时的C函数。那么,你怎么办呢?
好吧,线程不能被打断。所以你需要使用流程。 multiprocessing.Process
与threading.Thread
非常相似,只是它在子进程中运行代码而不是同一进程中的线程。
这意味着您无法与工作人员共享任何全局数据而不明确,但这通常是良好的事物。但是,它确实意味着输入数据(在这种情况下似乎不是任何东西)和输出(似乎是一个大字符串)必须是可选择的,并且显式地通过队列传递。这很容易做到;请阅读Exchanging objects between processes部分了解详情。
虽然我们正在努力,但您可能需要考虑重新考虑您的设计,以便根据任务而不是线程进行思考。如果您要下载200个PDF,那么您真的不需要200个线程;你想要8个或12个线程,所有线程都可以处理200个工作队列。 multiprocessing
模块支持进程池,但您可能会发现concurrent.futures
更适合此过程。 multiprocessing.Pool
和concurrent.futures.ProcessPoolExecutor
都允许你传递一个函数和一些参数,然后等待结果,而不必担心调度或队列或其他任何事情。