我正在尝试在脚本中实现多处理计数器,但不确定结果是否有意义。
# Global shared variable
total_bytes_written = multiprocessing.Value('i', 0)
# Worker method
def s3_put_worker(**kwargs):
global total_bytes_written
# local var that stores a data chunk length
data_chunk_len = len(data_chunk)
while not stop_event.is_set():
# do some work
# ...
# The counter that sums shared_total_written variable with local var
with total_bytes_written.get_lock():
total_bytes_written.value += data_chunk_len
# I'm using ProcessPoolExecutor to start several Gevent thread pools that runs my worker method
现在停止脚本后,我得到了那些奇怪的结果:
2018-11-06 04:42:55,412; [s3_stress.s3_stress_runner] (MainProcess : MainThread) INFO - Total bytes written to storage: -1946157056
我怀疑我无法将多处理共享var与本地方法的var相加,但是我找不到关于该主题以及如何解决该问题的任何信息。
谢谢
答案 0 :(得分:2)
您的问题似乎是由溢出引起的:Value('i', 0)
是一个带符号的32位整数,最多可以计数2147483647(用于字节计数大约为2GiB)。
>>> total_bytes_written = multiprocessing.Value('i', 0)
>>> total_bytes_written.value += 2147483647 # 2GiB - 1B
>>> total_bytes_written
<Synchronized wrapper for c_int(2147483647)>
>>> total_bytes_written.value += 1
>>> total_bytes_written
<Synchronized wrapper for c_int(-2147483648)>
Value
的最大data type是'Q'
的无符号long long(至少64位)。这可以处理范围[0, 18_446_744_073_709_551_615]
或最多16EiB的字节计数。如果您关心正确的符号处理,则已签名的long long类型'q'
仍可算到8EiB。
>>> total_bytes_written = multiprocessing.Value('q', 0)
>>> total_bytes_written.value += 9223372036854775807 # 8EiB - 1B
>>> total_bytes_written
<Synchronized wrapper for c_long(9223372036854775807)>