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
退出循环,而不是永远继续下去。
我想从外部动态控制蜘蛛,例如添加或停止 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
退出循环,而不是永远继续下去。