4

スレッド内で実行されている次のコードがあります (完全なコードはこちらです - 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

問題は、スレッドロックがオンになっていることです。各スレッドは基本的にシリアルに実行され、各ループが実行されるまでに時間がかかり、スレッドを使用する利点がなくなります。スレッド ロックを取り除く方法がない場合、try ステートメント内で for ループをより速く実行する方法はありますか?

4

2 に答える 2

6

StackOverflow に関する以前の回答によると、time.strptimeスレッドセーフではありません。残念ながら、その質問で言及されているエラーは、発生しているエラーとは異なります。

彼らの解決策はtime.strptime、スレッドを初期化する前に呼び出すことでした。その後time.strptime、さまざまなスレッドでの後続の呼び出しが機能します。

および標準ライブラリモジュールを確認した後、同じ解決策あなたの状況で機能する可能性があると思います。コードをローカルでテストできないため、うまくいくかどうかはわかりませんが、潜在的な解決策を提供したいと思います._strptimelocale

これがうまくいくかどうか教えてください。

編集:

もう少し調査を行ったところ、Python 標準ライブラリがC ヘッダー ファイルで呼び出しsetlocaleています。setlocale documentationlocale.hによると、これはスレッドセーフではなく、前述のように、スレッドを初期化する前に呼び出しを行う必要があります。setlocale

残念ながら、setlocaleを呼び出すたびに が呼び出されますtime.strptime。そこで、次のことを提案します。

  1. 前に説明したソリューションをテストしtime.strptime、スレッドを初期化する前に呼び出してロックを解除してみてください。
  2. #1 が機能しない場合は、ロケールモジュールtime.strptimeの Python ドキュメントに記載されているように、スレッド セーフな独自の関数をロールする必要があります。
于 2011-01-07T13:27:02.197 に答える
2

発生している問題は、使用されている関数とモジュールのスレッドセーフが欠落していることに関連しています。

ここでわかるように、tweepyは再入可能でもスレッドセーフでもありません。ここでわかるように、PythonLocaleTimeもそうではありません。

あなたのようなマルチスレッドアプリケーションの場合、同期された(RLockされた)独自のクラスを介してtweepyAPIをラップします。ただし、tweepyクラスから派生するのではなく、tweepyインスタンスのプライベート属性と関係を作成してください。

于 2011-01-07T14:08:54.240 に答える