Hi all, I’m building a simple program that concurrently save data to different shelve database with multithreading but error occurs when 2 threads invoke shelve.open() (for different files):
import threading
import shelve
import time
def parallel_shelve(idx):
print("thread {}: start".format(idx))
with shelve.open("cache_shelve_{}".format(idx)) as db:
time.sleep(4)
db["0"] = 0
db.close()
print("thread {}: done".format(idx))
if __name__ == "__main__":
threads = []
for idx in range(2):
threads += [threading.Thread(target=parallel_shelve, args=(idx,))]
for idx in range(len(threads)):
threads[idx].start()
for idx in range(len(threads)):
threads[idx].join()
Full log:
$ python multi_database.py
thread 0: start
thread 1: start
Exception in thread Thread-1:
Traceback (most recent call last):
File "/home/blahblah/anaconda3/lib/python3.9/threading.py", line 980, in _bootstrap_inner
Exception in thread Thread-2:
Traceback (most recent call last):
File "/home/blahblah/anaconda3/lib/python3.9/threading.py", line 980, in _bootstrap_inner
self.run()
File "/home/blahblah/anaconda3/lib/python3.9/threading.py", line 917, in run
self._target(*self._args, **self._kwargs)
File "/home/blahblah/Desktop/multi_database.py", line 8, in parallel_shelve
with shelve.open("cache_shelve_{}".format(idx)) as db:
File "/home/blahblah/anaconda3/lib/python3.9/shelve.py", line 243, in open
self.run()
File "/home/blahblah/anaconda3/lib/python3.9/threading.py", line 917, in run
return DbfilenameShelf(filename, flag, protocol, writeback)
File "/home/blahblah/anaconda3/lib/python3.9/shelve.py", line 227, in __init__
Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)
File "/home/blahblah/anaconda3/lib/python3.9/dbm/__init__.py", line 95, in open
return mod.open(file, flag, mode)
AttributeError: module 'dbm.gnu' has no attribute 'open'
self._target(*self._args, **self._kwargs)
File "/home/blahblah/Desktop/multi_database.py", line 8, in parallel_shelve
with shelve.open("cache_shelve_{}".format(idx)) as db:
File "/home/blahblah/anaconda3/lib/python3.9/shelve.py", line 243, in open
return DbfilenameShelf(filename, flag, protocol, writeback)
File "/home/blahblah/anaconda3/lib/python3.9/shelve.py", line 227, in __init__
Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)
File "/home/blahblah/anaconda3/lib/python3.9/dbm/__init__.py", line 95, in open
return mod.open(file, flag, mode)
AttributeError: module 'dbm.gnu' has no attribute 'open'
$ python --version
Python 3.9.13
The code works well shen accessing database files serially. How do I fix it to access different shelve files at the same time?