2017-06-14 98 views
1

我寫了一個使用python多線程庫執行API調用的腳本。它加速處理的利潤率巨大,因爲瓶頸是網絡,而不是我的主機上的任何東西(輸入某人說python在這裏沒有真正的多線程)。如何調試「pthread_cond_wait:資源繁忙」?

的問題是,有時當我運行該腳本,我收到此錯誤,用我的劇本最終掛/睡眠:

pthread_cond_wait: Resource busy 

我不知道如何找出爲什麼發生這種情況。我如何獲得更多的上下文來調試該問題?我是否需要將打印語句放在一堆隨機的地方,希望能夠解決導致此問題的任何問題?有沒有更好的調試方法?

如果有幫助,我這是怎麼實現的多線程:

for i in range(threads): # make the threads 
     t = threading.Thread(target=queue_worker, args=[apikey, q, retries, hit_threshold]) # The threads will use the "queue_worker" function with these parameters 
     t.daemon = True 
     t.start() # start the thread! 
# Data is put onto the queue and queue_worker does the API work here... 
... 
q.join() # Clean up and close the threads when the threads are all idle (no more data on the queue) 

編輯:

queue_worker,API和主代碼基本上是這樣的:

def queue_worker(apikey, q, retries, hit_threshold) 
    api_data = q.get() 
    for x in range(retries) 
     try: 
     response = do_api(api_data, apikey) 
     except Exception as error: 
     time.sleep(5) 
     continue 
    else: 
     error_count = error_count + 1 
     q.task_done() 
     continue 
    #... data parsing code here... 
    #... printing parsed data to screen here if a particular value returned is greater than "hit_threshold"... 
    q.task_done() 

def do_api(api_data, apikey) 
    params = { 'apikey': apikey, 'resource': api_data } 
    response = requests.get('https://MYURL.com/api', params=params, timeout=10) 
    return response 

if __name__ == '__main__': 
    threads = 50 
    q = Queue.Queue(threads) 
    for i in range(threads): # make the threads 
     t = threading.Thread(target=queue_worker, args=[apikey, q, retries, hit_threshold]) # The threads will use the "queue_worker" function with these parameters 
     t.daemon = True 
     t.start() # start the thread! 
    # Data is put onto the queue and queue_worker does the API work here... 
    ... 
    q.join() # Clean up and close the threads when the threads are all idle (no more data on the queue) 
+0

顯示你的'queue_worker'並解釋'apikey,q,retries,hit_threshold'。 – stovfl

+0

好的。我不得不保持半模糊,但希望這有助於。我將在稍後嘗試傳統的調試。這很難,因爲這個錯誤有時只會發生,並且只有在幾個小時的解析之後。 – Thisisstackoverflow

+0

@Thisisstackoverflow你有沒有得到這個解決方案 – vks

回答

1

評論:有關調試的任何提示?

  1. 雙檢使用自己Locks, Condition或其他threading功能爲代碼嵌套使用。
  2. 使用自己Locks訪問共享變量。
  3. 閱讀Python Threads and the Global Interpreter Lock 並嘗試此「解決辦法」。
    還有其他的方法來加速GIL操縱或避免:

    • 呼叫'time.sleep() '' - 設置 '' sys.setcheckinterval() '' - 在優化模式運行Python - 轉儲過程密集型任務爲C的擴展 - 使用子模塊來執行命令

可能的是,你所面對的Python GIL!

what-is-a-global-interpreter-lock-gil

一個其他線程擁有的鎖。
有不一致的使用鎖定。

+0

好吧,有趣的。有關調試的任何提示? – Thisisstackoverflow