2013-08-12 2 views
0

Я надеюсь на помощь многопоточности здесь. Я потратил два дня на поиски ответов, застрявших в точке, в которой я сейчас (текущее состояние кода ниже). Когда я запускаю это в pyscripter, я получаю печатный результат, как ожидалось (в моем классе потока), но без каких-либо ошибок. код, похоже, не может каким-то образом вернуться из потока. Я остаюсь в режиме отладки, не могу вырваться из него, без конца. Заранее благодарим за помощь и терпение; это моя первая попытка многопоточности.Ошибка многопоточности, процедура не заканчивается (зависает)

import urllib 
import urllib.error 
import urllib.request 
import datetime 
from bs4 import BeautifulSoup 
import csv 
import threading 
import queue 

q = queue.Queue() 
addrStrList = [] 
optionsRows = [] 

class OptionThread(threading.Thread): 
    def __init__(self, queue): 
     threading.Thread.__init__(self) 
     self.queue = queue 

    def run(self): 
     global optionsRows 
     while True: 
      webString = self.queue.get() 
      try: 
       with urllib.request.urlopen(webString) as url: page = url.read() 
       currMonth = webString[-2:] 
       soup = BeautifulSoup(page) 
       if (soup.text.find('There are no All Markets results for') == -1) & (soup.text.find('is no longer valid') == -1) & (soup.text.find('There is no Options data available') == -1): 
        tbls = soup.findAll('table') 
        if len(tbls[9]) > 1: 
         symb = webString[webString.find("=")+1: webString.find("&")] 
         expStrings = soup.findAll('td', text=True, attrs={'align': 'right'})[0].contents[0].split() 
         expDate = datetime.date(int(expStrings[6]), int(currMonth), int(expStrings[5].replace(',', ''))) 
         calls = extract_options(tbls[9], symb, 'Call', expDate) 
         puts = extract_options(tbls[13], symb, 'Put', expDate) 
         optionsRows = optionsRows + calls 
         optionsRows = optionsRows + puts 
         print("Options extracted for: " + symb + ", ExpDate: " + str(expDate)) 
      except urllib.error.HTTPError as err: 
       print(err.code) 
       pass 
##    if err.code == 404: 
##     pass 
##    else: 
##     raise 

class Option: 
    def __init__(self, UnderlyingSymb, PutCall, Strike, Exp, Symbol, Last, Chg, Bid, Ask, Vol, OpenInt): 

     self.DateDownloaded = datetime.date.today().strftime('%m/%d/%Y') 
     self.UnderlyingSymb = UnderlyingSymb 
     self.PutCall = PutCall 
     self.Strike = Strike 
     self.Exp = Exp 
     self.Symbol = Symbol 
     self.Last = Last 
     self.Chg = Chg 
     self.Bid = Bid 
     self.Ask = Ask 
     self.Vol = Vol 
     self.OpenInt = OpenInt 

    def ForCsv(self): 
     return [self.DateDownloaded, self.UnderlyingSymb, self.PutCall, self.Strike, self.Exp.strftime('%m/%d/%Y'), self.Symbol, self.Last, 
      self.Chg, self.Bid, self.Ask, self.Vol, self.OpenInt] 

def get_month(CurrentMonth, MonthsAhead): 
    cMonth = int(CurrentMonth) 
    cMonthsAhead = int(MonthsAhead) 
    if (cMonth + cMonthsAhead > 12): 
     tempMonth = (cMonth + cMonthsAhead) - 12 
    else: 
     tempMonth = cMonth + cMonthsAhead 
    if (tempMonth < 10): 
     return '0' + str(tempMonth) 
    else: 
     return tempMonth 

def extract_options(Options, Underlying, PutCall, Exp): 
    optionList = [] 
    #Loop over Options to check for null values 
    for op in range(1, len(Options)): 

     strike = Options.contents[op].contents[0].string 
     exp = Exp 
     symbol = Options.contents[op].contents[1].string 
     last = Options.contents[op].contents[2].string 
     change = Options.contents[op].contents[3].string 
     bid = Options.contents[op].contents[4].string 
     ask = Options.contents[op].contents[5].string 
     volume = Options.contents[op].contents[6].string 
     openInt = Options.contents[op].contents[7].string 

     if last == None: 
      last = 0 
     if change == None: 
      change = 0 
     if bid == None: 
      bid = 0 
     if ask == None: 
      ask = 0 
     if volume == None: 
      volume = 0 
     if openInt == None: 
      openInt = 0 

     optionList.append(Option(Underlying, PutCall, strike, exp, symbol, last, change, bid, ask, 
      volume, openInt)) 

    return optionList 

def create_address_strings(): 
    #read in symbol list 
    with open('C:/Users/krice_000/Desktop/MarketResearch/StockSymbolsForTestingThreading.csv', 'rt') as fp: 
     symbs = [s[0] for s in list(symb for symb in csv.reader(fp))] 

    #loop over the symbol list and make a list of complete address strings. 
    #http://finance.yahoo.com/q/op?s=HOV&m=2013-08 (Aug 2013 options chain) 
    baseStr = 'http://finance.yahoo.com/q/op?s=' 
    dayVar = datetime.date.today() 
    thisMonth = str(dayVar.month) 
    thisYear = str(dayVar.year) 
    for symb in symbs: 
     for month in range(1,13): 
      currMonth = get_month(thisMonth, month) 
      if (int(currMonth) < int(thisMonth)): 
       currYear = (int(thisYear) + 1) 
      else: 
       currYear = thisYear 
      addrStrList.append(baseStr + symb + '&m=' + str(currYear) + '-' + str(currMonth)) 

def write_options_to_csv(): 
     opts = [0] * (len(optionsRows)) 
     for option in range(0, len(optionsRows)): 
      opts[option] = optionsRows[option].ForCsv() 
     #Write to the csv file. 
     with open('C:/OptionsChains.csv', 'a', newline='') as fp: 
      a = csv.writer(fp, delimiter=',') 
      a.writerows(opts) 

def run_proc(): 
    create_address_strings() 
    for str in addrStrList: 
     q.put(str) 
    for i in range(5): 
     t = OptionThread(q) 
     #t.name = 'Thread' + str(i) 
     t.setDaemon(True) 
     t.start() 
    q.join() 
    write_options_to_csv() 

if __name__ == '__main__': 
    run_proc() 

ответ

1

queue.get() имеет аргумент block по умолчанию, который установлен в True по умолчанию, это означает, что очередь будет блокировать в случае необходимости, пока элемент не может ссылаться на available.You http://docs.python.org/2/library/queue.html для получения дополнительной информации.

оригинальных очереди код прибудут может измениться на:

try: 
    webString = self.queue.get(False) 
except: 
    print "queue is empty" 
    break 
+0

Спасибо .. Я вижу сообщение, выводимое на выход, но он по-прежнему не возвращает/отделки. – StatsViaCsh