V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
d29107d
V2EX  ›  Python

一个关于协程的 Python 面试题

  •  
  •   d29107d · 2023-05-15 02:52:23 +08:00 · 2315 次点击
    这是一个创建于 585 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前面试遇到这么一道有趣的题目,但是只给出一个输入用例,我写的代码可以通过这个输入用例,但是其它不知道的输入用例没法通过,不知道有没有大佬有啥思路吗?

    这个是题目的链接: https://drive.google.com/drive/folders/1KQ6LYQcbhdINcVB1ChayloO01oXR1hF6?usp=sharing

    import asyncio
    
    def main():
        async def do_sync_f():
            return sync_f()
    
        loop = asyncio.get_event_loop()
    
        task_g = loop.create_task(async_g())
        task_f = loop.create_task(do_sync_f())
    
        tasks = [
            task_g, task_f
        ]
    
        loop.run_until_complete(asyncio.wait(tasks))
    
        print(max(task_g.result(), task_f.result()))
    
    
    if __name__ == '__main__':
        main()
    
    6 条回复    2023-05-16 15:53:54 +08:00
    t133
        1
    t133  
       2023-05-15 05:46:34 +08:00 via iPhone
    有些 async 函数写的不好调用 run untill complete 你再调用 run untill complete 会出错
    NoAnyLove
        2
    NoAnyLove  
       2023-05-15 05:53:32 +08:00   ❤️ 2
    看了一遍题目,感觉你完全没理解这道题要考查什么。建议看看 https://docs.python.org/3/library/asyncio-task.html#running-in-threads ,另外,根据 python 版本不同,提供的函数不同。
    whitewinds
        3
    whitewinds  
       2023-05-15 21:28:04 +08:00
    你的这个写法并不正确,要知道 sync_f 里面的代码是会阻塞线程的,如果你 sync_f 和 async_g 都在主线程跑,那么如果 sync_f 先执行,event loop 就要等到 sync_f 解除阻塞才会执行 async_g ,那么 sync_f 和 async_g 并不 parallel ,你现在的代码之所以看起来并行,实际上是 async_g 先执行了,你可以在两个函数的开头写个 print 看看。

    调用顺序对 event loop 的影响如下

    import asyncio
    import time

    async def f():
    time.sleep(3)

    async def g():
    await asyncio.sleep(3)

    async def main():
    start = time.time()
    # await asyncio.gather(f(), g()) # cost 6.006543159484863
    # await asyncio.gather(g(), f()) # cost 3.0021119117736816
    print(f"cost {time.time()-start}")

    asyncio.run(main())

    所以,这题中 sync_f 必须放到另外的线程执行
    d29107d
        4
    d29107d  
    OP
       2023-05-15 22:22:25 +08:00 via Android
    @NoAnyLove 按照你的提示我终于理解了
    @whitewinds 是的 必须放两个线程才能并行
    enrolls
        5
    enrolls  
       2023-05-16 12:54:17 +08:00
    博客欢迎赐教。或者问一下 ChatGPT 吧,它协助你,通关比较快。
    likeyiyying
        6
    likeyiyying  
       2023-05-16 15:53:54 +08:00
    这是 GPT4 的回答,考察的应该是:asyncio.to_thread 这个知识点。

    You can use asyncio.to_thread() to run the synchronous function sync_f() in a separate thread, allowing it to run concurrently with the asynchronous function async_g(). Here's how you can achieve this:
    python

    Copy

    import asyncio
    import threading
    import time

    def sync_f(a=None):
    lock = threading.Lock()
    lock.acquire(blocking=False)
    lock.acquire(timeout=3)
    return 2

    async def async_g(a=None):
    await asyncio.sleep(3)
    return 1

    async def main():
    # Run sync_f() in a separate thread and async_g() concurrently
    sync_f_task = asyncio.to_thread(sync_f)
    async_g_task = async_g()

    results = await asyncio.gather(sync_f_task, async_g_task)
    print(results)

    if __name__ == "__main__":
    asyncio.run(main())
    This code will run both sync_f() and async_g() concurrently, and print their results once both are completed.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1177 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:19 · PVG 07:19 · LAX 15:19 · JFK 18:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.