2010-02-28 99 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

相關問題