【问题标题】:multiprocessing and async error: Task was destroyed but it is pending多处理和异步错误:任务被破坏但它正在等待
【发布时间】:2019-07-30 15:42:33
【问题描述】:

我是 asynco 的新手,但我是多线程和多处理的长期用户。 我真的想弄清楚这个错误出现在这里我做错了什么。

这是 python 3.7 中完全可运行的代码,它返回错误,因此任何人都可以对其进行测试。谁能告诉我我做错了什么,我的逻辑哪里出错了。非常感谢您的反馈。

import asyncio
import aiohttp
import logging
from time import sleep
from random import randrange
import multiprocessing as mp


class MainClass:

    def gather(self):
        urls = ['http://www.example.com/amount/appliance',
                'http://example.org/birthday',
                'http://www.example.com/']

        pool = mp.Pool(1)
        data = pool.map(self.tick_tack, urls)
        pool.close()
        pool.join()

        # print("final data")
        # print(data)

    def tick_tack(self, url):
        pid = mp.current_process().pid
        crawler = SecondClass(url)
        data = crawler.start()
        print((pid, data))
        return (pid, data)


class SecondClass():
    def __init__(self, url):
        self.conn_limiter = asyncio.BoundedSemaphore(10)
        self.session = aiohttp.ClientSession()
        self.url = url

    def start(self):
        future = asyncio.Task(self.crawl())
        loop = asyncio.get_event_loop()
        loop.run_until_complete(future)
        loop.close()
        result = future.result()
        return result

    async def crawl(self):
        print("- url", self.url)
        sleep(randrange(1,5))
        html = await self.http_request(self.url)
        await self.session.close()
        return html

    async def http_request(self, url):
        """Makes request on desired page and returns html result"""
        async with self.conn_limiter:
            try:
                async with self.session.get(url, timeout=30) as response:
                    html = await response.read()
                    return html
            except Exception as e:
                logging.warning('Exception at SecondClass.http_request: {}'.format(e))


if __name__ == '__main__':
    api = MainClass()
    api.gather()

【问题讨论】:

    标签: python python-3.x async-await python-asyncio aiohttp


    【解决方案1】:

    试试这个:

    import asyncio
    import aiohttp
    import logging
    from time import sleep
    from random import randrange
    import multiprocessing as mp
    
    
    class MainClass:
    
        def gather(self):
            urls = ['http://www.example.com/amount/appliance',
                    'http://example.org/birthday',
                    'http://www.example.com/']
    
            pool = mp.Pool(1)
            data = pool.map(self.tick_tack, urls)
            pool.close()
            pool.join()
    
            # print("final data")
            # print(data)
    
        def tick_tack(self, url):
            pid = mp.current_process().pid
            crawler = SecondClass(url)
            data = crawler.start()
            print((pid, data))
            return (pid, data)
    
    
    class SecondClass():
        def __init__(self, url):
            self.conn_limiter = asyncio.BoundedSemaphore(10)
            self.session = aiohttp.ClientSession()
            self.url = url
    
        def start(self):
            future = asyncio.Task(self.crawl())
            loop = asyncio.get_event_loop()
            loop.run_until_complete(future)
            #loop.close()
            result = future.result()
            return result
    
        async def crawl(self):
            print("- url", self.url)
            sleep(randrange(1,5))
            html = await self.http_request(self.url)
            await self.session.close()
            return html
    
        async def http_request(self, url):
            """Makes request on desired page and returns html result"""
            async with self.conn_limiter:
                try:
                    async with self.session.get(url, timeout=30) as response:
                        html = await response.read()
                        return html
                except Exception as e:
                    logging.warning('Exception at SecondClass.http_request: {}'.format(e))
    
    
    if __name__ == '__main__':
        api = MainClass()
        api.gather()
    

    结果:

    (16171, b'<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset="utf-8" />\n    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />\n    <meta name="viewport" content="width=device-width, initial-scale=1" />\n    <style type="text/css">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href="http://www.iana.org/domains/example">More information...</a></p>\n</div>\n</body>\n</html>\n')
    - url http://example.org/birthday
    (16171, b'<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset="utf-8" />\n    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />\n    <meta name="viewport" content="width=device-width, initial-scale=1" />\n    <style type="text/css">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href="http://www.iana.org/domains/example">More information...</a></p>\n</div>\n</body>\n</html>\n')
    - url http://www.example.com/
    (16171, b'<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset="utf-8" />\n    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />\n    <meta name="viewport" content="width=device-width, initial-scale=1" />\n    <style type="text/css">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href="http://www.iana.org/domains/example">More information...</a></p>\n</div>\n</body>\n</html>\n')
    
    Process finished with exit code 0
    

    您只能从SecondClass() 中删除loop.close(),因为这将阻止脚本运行所有任务...

    【讨论】:

    • 天哪,就这么简单,哈哈。非常感谢你!有时我们看不到森林里的树。
    猜你喜欢
    • 2016-02-29
    • 2021-11-08
    • 1970-01-01
    • 2017-01-08
    • 2016-06-25
    • 2017-04-29
    • 2016-08-06
    • 1970-01-01
    • 2019-08-09
    相关资源
    最近更新 更多