Исправлено исключение strptime с блокировкой потока, но программа замедляется - PullRequest
4 голосов
/ 07 января 2011

У меня есть следующий код, который при запуске внутри потока (полный код здесь - https://github.com/eWizardII/homobabel/blob/master/lovebird.py)

 for null in range(0,1):
            while True:
                try:
                    with open('C:/Twitter/tweets/user_0_' + str(self.id) + '.json', mode='w') as f:
                        f.write('[')
                        threadLock.acquire()
                        for i, seed in enumerate(Cursor(api.user_timeline,screen_name=self.ip).items(200)):
                            if i>0:
                                f.write(", ")
                            f.write("%s" % (json.dumps(dict(sc=seed.author.statuses_count))))
                            j = j + 1
                        threadLock.release()
                        f.write("]")
                except tweepy.TweepError, e:
                    with open('C:/Twitter/tweets/user_0_' + str(self.id) + '.json', mode='a') as f:
                        f.write("]")
                    print "ERROR on " + str(self.ip) + " Reason: ", e
                    with open('C:/Twitter/errors_0.txt', mode='a') as a_file:
                        new_ii = "ERROR on " + str(self.ip) + " Reason: " + str(e) + "\n"
                        a_file.write(new_ii)
                break

Теперь без блокировки потока я генерирую следующую ошибку:

Exception in thread Thread-117: Traceback (most recent call last):   File "C:\Python27\lib\threading.py", line 530, in __bootstrap_inner
    self.run()   File "C:/Twitter/homobabel/lovebird.py", line 62, in run
    for i, seed in enumerate(Cursor(api.user_timeline,screen_name=self.ip).items(200)): File "build\bdist.win-amd64\egg\tweepy\cursor.py", line 110, in next
    self.current_page = self.page_iterator.next()   File "build\bdist.win-amd64\egg\tweepy\cursor.py", line 85, in next
    items = self.method(page=self.current_page,
*self.args, **self.kargs)   File "build\bdist.win-amd64\egg\tweepy\binder.py", line 196, in _call
    return method.execute()   File "build\bdist.win-amd64\egg\tweepy\binder.py", line 182, in execute
    result = self.api.parser.parse(self, resp.read())   File "build\bdist.win-amd64\egg\tweepy\parsers.py", line 75, in parse
    result = model.parse_list(method.api, json)   File "build\bdist.win-amd64\egg\tweepy\models.py", line 38, in parse_list
    results.append(cls.parse(api, obj))   File "build\bdist.win-amd64\egg\tweepy\models.py", line 49, in parse
    user = User.parse(api, v)   File "build\bdist.win-amd64\egg\tweepy\models.py", line 86, in parse
    setattr(user, k, parse_datetime(v))   File "build\bdist.win-amd64\egg\tweepy\utils.py", line 17, in parse_datetime
    date = datetime(*(time.strptime(string, '%a %b %d %H:%M:%S +0000 %Y')[0:6]))   File "C:\Python27\lib\_strptime.py", line 454, in _strptime_time
    return _strptime(data_string, format)[0]   File "C:\Python27\lib\_strptime.py", line 300, in _strptime
    _TimeRE_cache = TimeRE()   File "C:\Python27\lib\_strptime.py", line 188, in __init__
    self.locale_time = LocaleTime()   File "C:\Python27\lib\_strptime.py", line 77, in __init__
    raise ValueError("locale changed during initialization") ValueError: locale changed during initialization

Проблема в том, что блокировка потока включена, каждый поток в основном работает сам по себе, и каждый цикл занимает много времени, чтобы иметь преимущество в наличии потока.способ избавиться от блокировки потока, есть ли способ, чтобы он выполнял цикл for внутри оператора try быстрее?

Ответы [ 2 ]

6 голосов
/ 07 января 2011

Согласно предыдущему ответу в StackOverflow, time.strptime не является поточно-ориентированным. К сожалению, ошибка в этом вопросе отличается от ошибки, с которой вы столкнулись.

Их решением было вызвать time.strptime до инициализации каких-либо потоков, а затем сработали бы последующие вызовы time.strptime в различных потоках.

Я думаю, что то же решение может работать в вашей ситуации после просмотра стандартных библиотечных модулей _strptime и locale. Я не уверен, что это сработает, поскольку я не могу проверить ваш код локально, но я подумал, что смогу предложить вам потенциальное решение.

Дайте мне знать, если это работает.

Edit:

Я провел немного больше исследований, и стандартная библиотека Python вызывает setlocale в заголовочном файле locale.h C. Согласно документации setlocale , это не поточно-ориентированный процесс, и вызовы setlocale должны выполняться до инициализации потоков, как я упоминал ранее.

К сожалению, setlocale вызывается каждый раз, когда вы звоните time.strptime. Итак, я предлагаю следующее:

  1. Проверьте решение, изложенное ранее, попробуйте вызвать time.strptime перед инициализацией потоков и снять блокировки.
  2. Если # 1 не работает, вам, вероятно, потребуется развернуть собственную функцию time.strptime, которая является поточно-ориентированной, как указано в документации по Python для модуля locale .
2 голосов
/ 07 января 2011

Проблема, с которой вы сталкиваетесь, связана с отсутствием безопасности потоков используемых функций и модулей.

Как вы можете видеть здесь , tweepy не является повторно входящим и не безопасным для потоков. Как вы можете видеть здесь , Python LocaleTime не слишком.

Для многопоточного приложения, подобного вашему, оберните API-интерфейс tweepy через ваш собственный класс, который синхронизируется (RLock'ed). Но не наследуется от класса tweepy, создайте отношение has-a с атрибутом private для экземпляра tweepy.

...