簡體   English   中英

python的異步C++庫

[英]Asynchronous C++ library for python

我正在努力解決一些希望這里有人能夠指導我完成的事情。

我有一個異步 python 代碼(asyncio),我用 C++ 編寫了一個與這個非常相似的簡單異步客戶端: https : //www.boost.org/doc/libs/1_74_0/doc/html/boost_asio/example/ cpp03/timeouts/async_tcp_client.cpp 出於測試目的,我有服務器,當客戶端連接時,它每 x 秒向客戶端發送一次消息。 我的計划是能夠從我的 python 代碼中使用這個客戶端,但問題是目前它阻止了我的事件循環,我真的不知道如何處理它。 有沒有辦法編寫可以從 python 代碼中等待的庫?

示例 C++ 庫:

void start_client(std::string ip, std::string port)
{
    try
    {
        boost::asio::io_context io_context;
        tcp::resolver r(io_context);
        // https://www.boost.org/doc/libs/1_74_0/doc/html/boost_asio/example/cpp03/timeouts/async_tcp_client.cpp
        client c(io_context);

        c.start(r.resolve(ip, port));

        io_context.run();  // this will block :(
        
    }
    catch (std::exception& e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }
}


#include <pybind11/pybind11.h>


PYBIND11_MODULE(async_client, m) {
    m.def("start_client", &start_client);
}

還有一些最小的可重現的python代碼:

import asyncio
import async_client 


async def client():
    async_client.start_client('0.0.0.0', '3000')  # this will block :(


async def test():
    while True:
        print('This will not get displayed!')
        await asyncio.sleep(3)


async def main():
    await asyncio.gather(client(), test())

if __name__ == '__main__':
    asyncio.run(main())

我已經嘗試在不同的線程中釋放 GIL 並運行 io_context,但我仍然需要一些無休止的過程,這樣它就不會跳出范圍並且仍然阻塞。

m.def("start_client", &start_client, pybind11::call_guard<pybind11::gil_scoped_release>() );

任何提示表示贊賞,謝謝。

為了使start_client不阻塞事件循環,您需要釋放 GIL,並將其交給 asyncio 管理的線程池(執行器)用於此目的:

async def client():
    loop = asyncio.get_event_loop()
    await loop.run_in_executor(
        None, async_client.start_client, '0.0.0.0', '3000'
    )

理想情況下,將連接 asyncio 和 boost_asio 事件循環,這樣就不需要線程,但這樣做可能是一項重大任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM