LoginSignup
1
0

More than 5 years have passed since last update.

Python2のdatetime.strptimeはスレッドセーフではない

Posted at

概要

python2でthreadingモジュールを使用して並列処理を実装した際に、datetimeのstrptime関数がエラーを吐いて、対処法について調べたのでその内容を記す。

検証環境

  • windows10
  • python2.7.11

再現コード

from datetime import datetime
import threading

def parse_time(datetime_str):
    print datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S")

threads = []
for _ in xrange(20):
    thread = threading.thread(target=parse_time,
                              args=["2018-01-01 12:34:56"])
    threads.append(thread)

for thread in threads:
    thread.start()

上記のようなコードを書いた場合に、実行時以下のようなエラーを吐く。

Exception in thread Thread-8:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
    self.run()
  File "C:\Python27\lib\threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "{実行ファイルまでのPath}", line 5, in parse_time
    print datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S.%f")
AttributeError: 'module' object has no attribute '_strptime'

原因

タイトルの通りPython2のstrptimeはスレッドセーフではないらしい。
探したらそれらしいIssueもある。だいぶ昔からある模様

対応

こちらを参考にした
threadingの処理が始まる前に、ダミーで一度呼べば良いそう。
なので先程のコードだと以下のように、threadがスタートする前に仮の呼び出しを一度行えばエラーが解消される。

"""前略"""
# 以下を追加。
datetime.strptime("2018-01-01 12:34:56", "%Y-%m-%d %H:%M:%S")

threads = []
for _ in xrange(20):
    thread = threading.thread(target=parse_time,
                              args=["2018-01-01 10:10:00.123456"])
    threads.append(thread)
"""後略"""

まとめ

動くようにはなったものの、対応方法が完全にバッドノウハウで悲しい。
なお、Python3.6.4で同様の処理を試したところ問題なく動作した。
Maya等のDCCでも早くPython3が使えるようになってほしい。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0