
task = []
def opreate(task): item = task.pop(0) dosomething... if(len(task) == 0): return opreate(task) opreate(task) 这样会造成栈无线堆积 RecursionError: maximum recursion depth exceeded while calling a Python object
大佬们,请问有什么方法可以持续操作列表的,每次取出一个,直到列表清空,我需要等每一个 item 里面操作完再进行下一个 item ,循环不是很满足
1 lyang 2022-07-21 14:46:28 +08:00 ``` def opreate(item): dosomething... for item in task: opreate(item) ``` |
4 reter 2022-07-21 16:15:27 +08:00 python 不是有一个 GIL 锁吗,理论上是可以多线程同时操作同一个列表对象的。当然最好的方法还是用自带的 Queue (有多线程和多进程的版本). |
5 wxf666 2022-07-21 16:24:20 +08:00 @PEax 这样? def sum_of_squares(items): def square(n: int): time.sleep(1) return n ** 2 with ThreadPoolExecutor(max_workers=4) as executor: return sum(executor.map(square, items)) if __name__ == '__main__': print(sum_of_squares(range(1, 10 + 1))) # 1^2 + 2^2 + ... + 10^2 |
6 skies457 2022-07-21 16:30:30 +08:00 这个东西叫 tail recursion https://stackoverflow.com/questions/13591970/does-python-optimize-tail-recursion |
7 fbichijing 2022-07-21 16:32:30 +08:00 直接用 queue 不就完事了吗? |
8 ispinfx 2022-07-21 16:56:12 +08:00 > 持续操作列表的,每次取出一个,直到列表清空 同楼上 |
9 sujin190 2022-07-21 17:38:51 +08:00 while task: item = task.pop(0) dosomething... while 循环处理就是了啊,干嘛要递归调用 |
10 a href="/member/renmu123" class="dark">renmu123 2022-07-21 17:48:44 +08:00 via Android 你用多线程为什么还要等一个操作完再操作另一个,迷惑行为。 这种需求直接单线程不就行了,只要你的操作不是异步的 |
11 jmqrock2020 2022-07-22 10:23:49 +08:00 多线程的 CPU 时间片的分配,应该是看调用操作是不是原子的,如果非原子的那么可能在没有完成时就会被切换至其他线程。GIL 只是锁住了并行度,并不能保证线程安全。我的理解可能说的不对,欢迎指正。 @reter |
12 reter 2022-07-22 22:33:38 +08:00 我认为是对的。但是 python 是解释型语言,应该先从解释器角度去理解。 比如 https://docs.python.org/3/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe 描述到,python 解释器的执行单元是字节码指令。字节码指令背后的所有 C 语言代码执行也是“原子操作”。当一个字节码成功执行后,其他线程才有机会拿到 GIL 。 CPU 还有各种缓存和指令执行顺序问题,那就更加复杂了。 @jmqrock2020 总之,有多线程就要考虑并发读写变量的情况 |