2008-09-15 76 views
1

当试图实现一个异步API调用/非阻塞调用时,我在All Plain-C应用程序中了解了一点,我通过'委托'读了一个关于APM(异步编程模型)的内容。基本上我想要做的是调用一个API f1()来完成一项功能(需要很长的时间8-10秒),所以我称之为API f1(),忘记它,然后继续做其他工作,例如, I/O用于获取下一个f1()调用的数据或某些不依赖于f1()的结果的功能。异步API

如果任何人使用该APM模型的编程,我正在寻找一些简明的解释来实现非阻塞调用。

是否有任何其他的方式来实现异步API,任何其他库或框架可能有助于此?

回答

0

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

1

您基本上需要创建一个多线程(或多进程)应用程序。 f1()API需要生成一个线程(或进程)来处理独立执行空间中的数据。当它完成时,f1()例程需要通知主进程执行完成(signal(),消息队列等)。

1

一个在普通C程序中进行异步编程的流行方式是使用“事件循环”。有许多库可以使用。我建议看看 glib

另一种替代方法是使用多个预占线程(每个并发操作一个线程),并将它们与互斥锁和条件变量同步。然而,在普通C中的先发制人的线程是我会避免的,特别是如果你想编写可移植的程序。很难知道哪些库函数是可重入的,线程化程序中的信号处理是一件麻烦事,一般来说C库和系统函数都是为单线程使用而设计的。

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

1

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

使用任何形式的事件循环的问题是不知道你的循环的外部函数永远不会控制回到你的循环。因此,你不会做任何事情。

0

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

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

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