【问题标题】:Asynchronous APIs异步 API
【发布时间】:2010-09-08 21:44:10
【问题描述】:

在尝试实现异步 API 调用/非阻塞调用时,我对我拥有的 All Plain-C 应用程序了解一点,我读到了“Delegates”的一篇关于 APM(异步编程模型)的文章。基本上我想做的是调用一个 API f1() 来做一个功能(这需要很长时间 8-10 秒),所以我调用那个 API f1(),忘了它,并继续做一些其他的工作,例如用于获取数据以供下次调用 f1() 或某些不依赖于 f1() 结果的功能的 I/O。

如果有人使用过 APM 编程模型,我正在寻找一些关于实现非阻塞调用的简明解释。

还有其他实现异步 API 的方法,任何其他可能对此有所帮助的库/框架吗?

【问题讨论】:

    标签: c asynchronous api


    【解决方案1】:

    嗯。基本上我见过两种异步 API:

    1. 中断。您给呼叫一个回调,该回调应在呼叫之后执行。 GIO(前面提到的 GLib 的一部分)以这种方式工作。它相对容易编程,但您通常会更改运行回调的线程(除非它与主循环集成,如 GIO)。
    2. 投票。您检查数据是否可用。众所周知的 BSD 套接字以这种方式运行。它的优点是不必与主循环集成并在特定线程中运行回调。

    如果您为 Gnome 或基于 Gtk+ 的程序编程,我想补充一点,GTask 似乎非常好(可能很好?我没用过)。 Vala 将更好地支持类似 GIO 的异步调用。

    【讨论】:

      【解决方案2】:

      如果您所指的函数 f1() 本身不是以异步方式实现的,则您需要自己将其包装在自己的线程中。执行此操作时,您需要注意可能由调用的特定函数引起的副作用。许多库不是以线程安全的方式设计的,从这些库中多次并发调用函数会导致数据损坏。在这种情况下,您可能需要将功能封装在外部工作进程中。对于您提到的繁重工作(8-10 秒),开销可能是可以接受的。如果您一次只在一个线程中使用外部非线程安全函数,那么您可能是安全的。

      使用任何形式的事件循环的问题在于,不知道您的循环的外部函数永远不会将控制权交还给您的循环。因此,您将不会做任何其他事情。

      【讨论】:

        【解决方案3】:

        在纯 C 程序中进行异步编程的一种流行方法是使用“事件循环”。您可以使用许多库。我建议看看 glib.

        另一种选择是使用多个抢占式线程(每个并发操作一个)并将它们与互斥锁和条件变量同步。但是,我会避免使用纯 C 语言中的抢占式线程,尤其是在您想编写可移植程序时。很难知道哪些库函数是可重入的,线程程序中的信号处理很麻烦,而且通常 C 库和系统函数都是为单线程使用而设计的。

        如果您打算只在一个平台(如 Windows)上运行您的应用程序,并且使用 f1() 完成的工作相对简单,那么线程化就可以了。

        【讨论】:

          【解决方案4】:

          您基本上需要创建一个多线程(或多进程)应用程序。 f1() API 需要生成一个线程(或进程)以在单独的执行空间中处理数据。完成后,f1() 例程需要向主进程发出执行完成的信号(signal()、消息队列等)。

          【讨论】:

            【解决方案5】:

            用指向 C 中函数的指针替换委托,其他一切都与您所读到的基本相同。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-01-14
              • 1970-01-01
              • 2020-11-10
              • 2022-12-11
              • 1970-01-01
              • 1970-01-01
              • 2011-01-09
              相关资源
              最近更新 更多