2010-02-28 77 views
1

我有一个代码库,我正在寻找拆分并添加到使用线程,但我是如何处理它相对较新。请在阅读进一步的尊重之前,我不希望重写这段代码,并在问题解决后将其抛回给我。我更愿意把某个人指向正确的方向,而不是为我解决问题。我没有很好地学习。将python程序转换为线程应用程序的过程?

全功能代码库为here - 它需要通过easy_install安装的mechanize和beautifulsoup库。

我把所有的函数都分开了,并尽量保持代码尽可能干净(我确信在那里有一些优化,我会得到扩展,但主要问题是如何线穿过这个。

我的最终目标是要打包成一个线程这一点,然后共享其他浏览器初始化对象之间的cookies为了做其他的事情,而我原来的代码运行“中背景”。

我已经如此尝试:

class Recon(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     #Packed the stuff above my original while loop in here, minus functions. 
    def run(self): 
     #Packed my code past the while loop in here. 
somevar = Recon() 
somevar.start() 

问题我遇到的是,一旦我运行该程序,它将运行init中的内容,但之后它只是坐在那里冻结在我身上。没有追踪,没有错误,只是没有做任何事情,甚至不会将我的命令提示返回到我的控制。

我可以只是得到一些提示,或者如何转换的一般流程?我感到不知所措,并删除了我正在尝试的代码,所以我没有这个例子,但是我需要预先加入“自我”。我所有的变数?我需要将我的变量定义为全局吗?

这是我在尝试将脚本转换为使用threading后遇到的问题的复制。

回答

3

只要你有一个单一的线程(如上面的代码片段,你只需要一次实例化Recon),你应该做什么并不重要;但是我当然想象你引入线程的原因是最终转向有多个线程处于活动状态。

如果是这样的话,那么第一个关键问题是确保你永远不会有两个或更多的线程同时尝试使用相同的共享系统/资源 - 例如,多个线程同时写入ReconFile,在你提到的pastebin URL代码的情况下。

避免这种问题的经典方法是使用锁定,但我最喜欢的方式是非常不同的:确保任何此类资源仅由一个专用线程访问,并使用Queue.Queue实例(本质上是线程安全)其他线程向专用线程发布工作请求(因此,不是直接写入ReconFile,而是每个其他线程都会使连续写入的行的列表成为.put队列中“recon文件写入”工作线程正在等待的列表通过.get)。

当您需要从这些操作中取回结果(这里不是这种情况)时,请求线程会将其自己的“返回结果的队列”作为其放入“工作请求包”的一部分工作线程的队列。我已经在“Python in a Nutshell”第2版的线程章节中介绍了有关此推荐体系结构的更多详细信息(以及为什么,作为本书的作者,我当然从不会推荐您执行非法下载免费海盗我的书的副本,但我可以提到有很多网站提供此类海盗副本下载 - 免费阅读我的书的合法方式是注册O'Reilly的"safari"在线图书网站的试用优惠。

这并没有解决你正在观察的具体问题,因为当你只有一个线程时就会发生这种情况。我注意到线程试图在标准输入和标准输出上执行大量的I/O,这可能是线程可能产生的问题 - 考虑在线程之前执行之前(在主线程中)以及为需要的输出使用Python的标准logging模块,其中保证是线程安全的。你还在观察问题吗?如果是这样的话,那么下一步就是用logging.info来打电话给你的代码,这样你就可以准确地确定它在哪里停滞 - 并告诉我们关于它的所有信息,所以我们可以尝试从那里获得帮助!

+0

你所有的假设都是正确的;我正在尝试引入线程,为将来只能共享列表和cookiejar对象的代码做准备。我的想法是,我将用一个线程来抓取数据,并在另一个线程中处理该数据(但被访问的数据将永远不会被同时访问) 如果我调用init,并运行...如果我的init正在调用原始输入,Python会在等待init输入时运行我的run函数吗?或者init是否必须先完成? – ThantiK 2010-02-28 04:39:19

+0

@ThantiK,Python中的所有I/O函数“放弃GIL”(全局解释器锁),以便其他线程(使用CPU任务而不是I/O)可以接管。但是线程子类的'__init__'运行在实例化它的线程中(主线程在正常情况下,特别是在你的情况下) - 新线程只在'start'方法调用时产生,它是什么运行只是“运行”方法。 – 2010-02-28 05:03:57

+0

这是我的转换的结果,SEEMS现在工作正常:http://pastebin.com/Pb582aF3任何帮助使它更清洁或任何批评是受欢迎的;) – ThantiK 2010-02-28 05:06:03

相关问题