4

openpyxl はスレッドセーフですか? あるスレッドがワークシートを変更し、別のスレッドが定期的に保存することを望んでいます。変更操作と保存操作の周りにロックオブジェクトを追加する必要があるのか​​ 、それともopenpyxlにすでに組み込まれているのか疑問に思っていました. ドキュメントにも openpyxl のスレッドに関する以前の質問もありませんでした。

あなたの答えを読んだ後、私は次のテストを実行しました:

import threading 
import random 
import time 
from openpyxl import Workbook

wb = Workbook() 

class openpyxlwriting ( threading.Thread): 

    def run ( self ): 

        global wb
        ws = wb.get_active_sheet()
        c = 1 
        for a in range(100):
            for b in range(10000):
                ws.cell(column = a,row=b).value = c
                c += 1
            print "row ",a

class openpyxlsaving ( threading.Thread): 

    def run ( self ): 

        global wb

        for a in range(1000): 
            wb.save('test.xlsx')
            print "saved"

openpyxlwriting().start()
time.sleep(1)
openpyxlsaving ().start()

これにより、次のトラスバックが得られました: trasback.png

4

2 に答える 2

4

「OpenPyXl はスレッド セーフです。ワークブックは異なるスレッドで同時に作成できます。ただし、各ワークブックは一度に 1 つのスレッドでのみ変更する必要があります。」

フォームhttps://bitbucket.org/openpyxl/openpyxl/issues/228/

于 2013-09-03T01:04:24.310 に答える
2

これをテストできるかどうかを確認することにしたので、以下の単純なプログラムを作成しました。このプログラムは、ランダムなスリープをスローして、同じセルの読み取りと書き込みを試行する一連のスレッドを生成します。

問題を示している可能性のある OS エラーは見当たりませんでした。一方で、よくわからない動作もいくつか見られました。スレッド数が増えると、完了したループの数が減少しました。したがって、たとえば、スレッド 100 はループを 8 回通過しただけです。これは、何らかのエラーであるか、スレッド セーフの問題を示している可能性があります。

とにかく、これは自分でテストするための出発点となるはずです。

import threading
import random
import time
from openpyxl import Workbook

wb = Workbook()
ws = wb.get_active_sheet()
testcell = ws.cell('B9')
counter = 1

class openpyxlworker ( threading.Thread):

    def run ( self ):

        global wb     
        global testcell
        global counter

        for a in range(1000):
            time.sleep(random.random()/100)
            writing = random.randrange(1, 1000)
            testcell.value = writing
            time.sleep(random.random()/100)
            reading = testcell.value          
            print "Thread " + str(counter) + " wrote " + str(writing) + " and read " + str(reading)
            time.sleep(random.random()/100)
            wb.save('test.xlsx')

        counter = counter + 1

for b in range(100):
    openpyxlworker().start()
于 2012-06-28T01:02:44.680 に答える