求助 Python 多线程下的一个诡异问题,求解惑(20 行代码)

2020-02-25 16:36:26 +08:00
 JL1990
from concurrent.futures import ThreadPoolExecutor

insert_executor = ThreadPoolExecutor(max_workers=20)
_TOTAL_TEST_DATA_NUMBERS = 5000000
_INSERT_DATA_BLOCK_SIZE = 500


def data_generator():
    ret_data = []
    for i in range(1, _TOTAL_TEST_DATA_NUMBERS + 1):
        data = {"id": i}
        ret_data.append(data)
        if len(ret_data) >= _INSERT_DATA_BLOCK_SIZE:
            yield ret_data
            ret_data.clear()
    yield ret_data


def data_process(data):
    value = max(data, key=lambda item: item["id"])
    print("max id {}".format(value["id"]))


if __name__ == '__main__':
    dg = data_generator()
    for d in dg:
        insert_executor.submit(data_process, d)


data_generator,生成一个大小是 500 的数组,最大 id 是 5000000,理论上每次生成的最大 id 是能被 500 整除的。

实际上,data_process 打印出来的 id,总是会出现类似 4855854 这样的不规则数字,和 data_generator 函数生成的数据理论上不一致,请问是什么原因?有大哥指导一下吗?

1209 次点击
所在节点    问与答
4 条回复
ccpp132
2020-02-25 16:39:37 +08:00
ret_data.clear() 改成 ret_data = []
理解一下引用
JL1990
2020-02-25 16:54:30 +08:00
@ccpp132 #1 大哥,你说的好像是对的,不过这里只有一个 ret_data,怎么又和引用扯上关系了呢?
sessionreckon
2020-02-25 17:05:27 +08:00
@JL1990
线程池里还没有算完 max,对应的 ret_data 已经被修改了
所以有问题,你不用线程池,或者 new 一个新的 list 都可以解决问题
再说了,一个计算密集型的 max 计算用什么线程池
JL1990
2020-02-25 17:11:39 +08:00
@sessionreckon #3 感谢,明白原因了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/647442

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX