Python 无法从外部停止协程中的 while 循环

Python cannot stop a while loop in coroutine externally

我想从外部动态控制蜘蛛,例如添加或停止 a,如何解决?

以及在class定义self._loop=asyncio.get_event_loop()之后开始加注:

File "Python38\lib\multiprocessing\spawn.py", line 102, in spawn_main
    source_process = _winapi.OpenProcess(
OSError: [WinError 87] The parameter is incorrect

为什么?

我的平台是Windows.

import asyncio
from multiprocessing import Process


class Spider(Process):
    def __init__(self):
        super().__init__()
        self._stopped = False

    def run(self):
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.fetching())

    async def fetching(self):
        while True:
            if self._stopped:  # not update variable
                await asyncio.sleep(1)
                continue
            print("fetching...")
            await asyncio.sleep(1)

    def stop(self):
        self._stopped = True
        print('stop', self._stopped)


if __name__ == "__main__":
    import time

    s = Spider()
    s.start()
    time.sleep(2)
    s.stop()

输出是:

fetching...
fetching...
stop True
fetching...
fetching...

您应该在这两个进程(主进程和您创建的进程)之间使用共享内存。考虑使用 Value

修复了您的代码:

import asyncio
from ctypes import c_bool
from multiprocessing import Process, Value


class Spider(Process):
    def __init__(self):
        super().__init__()
        self._stopped = Value(c_bool, False)  # <== here

    def run(self):
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.fetching())

    async def fetching(self):
        while True:
            if self._stopped.value:  # <== here
                await asyncio.sleep(1)
                continue
            print("fetching...")
            await asyncio.sleep(1)

    def stop(self):
        self._stopped.value = True  # <== here
        print('stop', self._stopped)


if __name__ == "__main__":
    import time

    s = Spider()
    s.start()
    time.sleep(2)
    s.stop()

但老实说,如果您得到 "stopped" 值为 True,您应该 break 退出循环,而不是永远继续下去。