【问题标题】:Does calling a blocking function inside libev event callback function blocks whole app?在 libev 事件回调函数中调用阻塞函数会阻塞整个应用程序吗?
【发布时间】:2017-07-30 01:50:25
【问题描述】:

我使用 libev 来开发我的事件驱动应用程序。我喜欢在事件中查询远程 mysql 服务器。所以, mysql_real_connect 阻止整个应用程序或只是 my_read_cb

根据以下代码

my_read_cb(EV_P_ ev_io *w, int revents) {

    mysql_real_connect(*mysql, "host", "user", "pass", "db", 3306, NULL, 0);
}


struct ev_loop *loop = ev_default_loop(0);
ev_io_init(io, my_read_cb, network_fd, EV_READ);
ev_io_start(loop, io);
ev_run(loop, 0);

【问题讨论】:

    标签: c event-driven mysql-connect libev


    【解决方案1】:

    它阻塞了整个应用程序,因为回调函数 my_read_cb()ev_run() 函数在同一个(也称为主)线程中执行。 这就是reactor pattern 的工作方式,您的代码应该是“非阻塞”的,这意味着您应该避免任何 I/O 等待、sleep() 调用、互斥等待等。使用传统的阻塞代码很难遵循这样的要求来自各种库,例如您的 MySQL 驱动程序。

    有(至少)三种解决方法:

    • 接受事件循环不时被阻塞的事实。在某些应用中,这可能不是什么大问题。
    • 实现proactor pattern - 这基本上意味着每个处理程序回调都在不同于主线程的工作线程中执行,因此,事件循环不会被阻塞。这就是 Node.js 提供的或在 C 世界中提供的 libuv 等等。
    • 找到与您的事件循环兼容的库的异步/非阻塞实现。你需要在这里特别幸运。一个例子是例如https://c-ares.haxx.se 用于异步 DNS 解析(与 getaddrinfo 系列中的 POSIX 系统 DNS 阻止调用相反)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多