Jac*_*cob 5 python thread-safety openpyxl
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()
Run Code Online (Sandbox Code Playgroud)
这给了我以下 trasback: trasback.png
“OpenPyXl 是线程安全的;工作簿可以由不同的线程同时创建。但是,每个工作簿一次只能由一个线程修改。”
表格https://bitbucket.org/openpyxl/openpyxl/issues/228/
我决定看看是否可以对此进行测试,因此我创建了下面的简单程序,该程序生成一堆尝试读取和写入同一单元格的线程,并插入随机睡眠。
我没有看到任何可能表明存在问题的操作系统错误。另一方面,我确实看到了一些我不太理解的行为。随着线程数的增加,完成的循环数减少。因此,例如,线程 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()
Run Code Online (Sandbox Code Playgroud)