终于写完了 单测也测完了 至少我是很满意的
```python3
BUF_SIZE = 4 * 1024 * 1024 # 4MiB
BUF_PRE_FETCH = 64 # 最多消耗 256MiB 额外内存
def cal_hashes(f:
typing.IO):
f.seek(0)
res = {
'finish': False,
}
queues = {
'md5': Queue(),
'sha1': Queue(),
'sha256': Queue(),
}
def _producer(_f:
typing.IO):
while True:
time.sleep(0.01)
empty_flag = True
for _, queue in queues.items():
if not queue.empty():
empty_flag = False
break
if empty_flag:
count = BUF_PRE_FETCH
while count > 0:
count -= 1
content = _f.read(BUF_SIZE)
if not content:
res['finish'] = True
return
for _, queue in queues.items():
queue.put_nowait(content)
# 合理的相信算完 256M 的数据
# 至少需要这么久
# 树莓派 4:120MiB/s
# 8 代 i5: 370MiB/s
time.sleep(0.3)
def _consumer(_algo: str):
hash_obj = hashlib.new(_algo)
while True:
if res['finish'] and queues[_algo].empty():
break
try:
content = queues[_algo].get(timeout=1)
except Empty:
continue
hash_obj.update(content)
queues[_algo].task_done()
res[_algo] = hash_obj.hexdigest().upper()
ths = []
producer = threading.Thread(target=_producer, args=(f,))
producer.start()
ths.append(producer)
for algorithm in queues.keys():
consumer = threading.Thread(target=_consumer, args=(algorithm,))
consumer.start()
ths.append(consumer)
for th in ths:
th.join()
return res
```