通过Asynci解决http python函数的阻塞问题

2024-04-18 17:34:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在实现一个通过http请求(inspired by this blogpost)进行通信的区块链。这个区块链有一个工作证明方法,根据难度,可以在相当长的时间内阻止其他http请求。这就是为什么我试图从python实现新的asyncio特性。以下工作:

async def proof_of_work(self, last_proof):
    """
    Simple Proof of Work Algorithm:
     - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
    """
    proof = 0
    while self.valid_proof(last_proof, proof) is False:
        proof += 1
        await asyncio.sleep(1)

    return proof

然而,这使得我的工作证明非常缓慢,我想这是因为它在每次迭代之后都被迫休眠。有什么更优雅的方法来解决这个问题呢?在

^{pr2}$

会加快一点,但看起来有点脏。正确的实施方法是什么?在


Tags: of方法self证明asynciohttpbyis
1条回答
网友
1楼 · 发布于 2024-04-18 17:34:16

如果您想在协同程序中运行CPU阻塞代码,应该使用run_in_executor()在单独的执行流中运行它(以避免异步的事件循环冻结)。在

如果您只想使用另一个执行流,或者(我认为更好)使用ThreadPoolExecutor将与CPU相关的工作委托给其他核心。在

import asyncio
from concurrent.futures import ProcessPoolExecutor
import hashlib


# ORIGINAL VERSION:
# https://github.com/dvf/blockchain/blob/master/blockchain.py
def valid_proof(last_proof, proof):
    guess = f'{last_proof}{proof}'.encode()
    guess_hash = hashlib.sha256(guess).hexdigest()
    return guess_hash[:4] == "0000"


def proof_of_work(last_proof):
    proof = 0
    while valid_proof(last_proof, proof) is False:
        proof += 1
    return proof


# ASYNC VERSION:
async def async_proof_of_work(last_proof):
    proof = await loop.run_in_executor(_executor, proof_of_work, last_proof)
    return proof


async def main():
    proof = await async_proof_of_work(0)
    print(proof)


if __name__ ==  '__main__':
    _executor = ProcessPoolExecutor(4)

    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main())
    finally:
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()

输出:

^{pr2}$

相关问题 更多 >