gpt4 book ai didi

python-3.x - 信号量 Python 是如何工作的

转载 作者:行者123 更新时间:2023-12-05 03:26:56 24 4
gpt4 key购买 nike

我想检查大约 100 个 ips 地址的可达性,并使用信号量设置并发任务的限制。但是现在我不确定它是如何工作的或者为什么它在代码示例中不起作用。正如我所观察到的,“task_reachable”函数仍然正确执行。如果无法访问地址,则在“try_ssh_connection”中“所有”任务并行执行,这会使代码非常慢。

class test_class():
def __init__(self):
self.username = "username"
self.password = "password"

self.ips = open("open_ip_list")

def create_async(self):

asyncio.run(self.create_tasks())

async def boundary_task(self,ip):
sem = asyncio.Semaphore(2)
async with sem:
return await self.task_reachable(ip)

async def create_tasks(self):
timer = Timer(text=f" task time: {{:.1f}}")
timer.start()
tasks = [
asyncio.ensure_future(self.boundary_task(i))
for i
in self.ips
]
await asyncio.gather(*tasks)
timer.stop()

async def task_reachable(self, ip):
url = "http://" + ip.strip("\n") + "/example_website.html"
session = aiohttp.ClientSession()
try:
resp = await session.get(url, ssl=False, timeout = 1)
await resp.read()
await session.close()

except:
await session.close()
await self.try_ssh_connection(ip, url)
await session.close()

async def try_ssh_connection(self, host, url):
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=self.username, password=self.password)
print("go")

except paramiko.AuthenticationException:
print( "Username or Password wrong!")
await self.stop_fun()

except OSError:
print("Network is not reachable")
await self.stop_fun()

async def stop_fun(self):
stop_event = asyncio.Event()
try:
stop_event.set()
except RuntimeError:
pass

if __name__ == "__main__":
app = test_class()
app.create_async()

最佳答案

您的问题是 boundary_task 的每个运行实例都有自己的信号量。

async def boundary_task(self, ip):
sem = asyncio.Semaphore(2)

如果您希望它们都使用相同的信号量,boundary_task 的所有实例都需要共享它。

async def boundary_task(self, ip, semaphore):
async with sem:
return await self.task_reachable(ip)

async def create_tasks(self):
sem = asyncio.Semaphore(2)
tasks = [
self.boundary_task(i, sem)
for i
in self.ips
]
await asyncio.gather(*tasks)

由于您使用的是类,因此您还可以在 __init__ 中创建信号量。

def __init__(self):
...

self.sem = asyncio.Semaphore(2)

async def boundary_task(self, ip):
async with self.sem:
return await self.task_reachable(ip)

关于python-3.x - 信号量 Python 是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71572375/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com