代码之家  ›  专栏  ›  技术社区  ›  Wim ten Brink

进程间通信

  •  14
  • Wim ten Brink  · 技术社区  · 15 年前

    我有两个应用程序:X和Y。
    X是主要的应用程序,它处理许多XML文件。它有超过10年的历史,已经使用了6种技术来存储、处理和处理这些XML文件。
    Y是我正在开发的一个调试工具,它可以以一种更为人可读的形式处理和显示XML文件。基本上,它只有一个样式表集合,用于检测XML格式,如果它识别了该格式,它将把XML转换为HTML,HTML显示在twebbrowser组件中。

    问题:
    当Y处于活动状态时,我希望X将它处理的任何XML发送到Y,以便显示。但只有当你跑的时候!如果y不运行,x就什么也不做。
    Y的检测需要在任何时候进行,并且需要快速。我考虑过使用TCP/IP通信,但是由于缺少Y而导致的延迟太长了。尤其是因为有时会处理很多XML。命名管道和类似的基于网络的解决方案也存在同样的问题。我需要快速确定Y是否正在运行并且可用,如果是,请快速发送XML,然后继续X。
    我还考虑让Y成为一个基于COM的应用程序,或者添加一个基于COM的DLL,其中包含允许进程间通信的事件。DLL解决方案很有趣,因为它将向X公开一个方法来上载XML文件,然后向Y发送一个事件来处理XML。 这似乎是最好的选择 尽管我还需要检查DLL是否已注册。如果不是,那么X甚至不能称之为它!
    应用程序X也将由不接收Y或附加dll的客户使用,因此在大多数情况下,不会注册dll。(正如我所说,这是为了在调试期间提供帮助…)

    但也许还有其他选择?TCP/IP太慢,COM有点太复杂。


    X和Y将在同一系统上运行。或者只有X在系统上,Y完全丢失。


    关于使用内存映射文件…虽然实用,但我需要记住,大多数情况下,Y不会运行,因此MMF会浪费内存。在X中,XML数据的大小可以达到4 MB,因此在内存中有多个这样大小的块有点过分。它可以用于在X和Y之间发送状态消息,但内存有时会对应用程序X造成一些问题。虽然MMF可以连接到物理文件,但我试图避免编写任何临时文件。
    这是一个很好的解决方案,但恐怕不够好。


    我想,还有一些解释是合理的。应用程序X是一个将被使用几个小时的应用程序,用户执行大量的操作,这些操作将转换为大量得到处理的XML数据。应用程序X是一个桌面应用程序,它与多个Web应用程序(REST)、Web服务(SOAP)和其他应用程序通信,其中大部分是通过XML实现的。
    应用程序Y只是为了窥视X正在运行的进程。基本上,X工作20分钟,Y弹出。从那一刻起,X应该开始向Y发送XML,直到Y再次消失或者X终止。在大多数情况下,Y运行只是为了捕获正在运行的任务的一小部分,甚至可能启动多次。但我可能是在错误地考虑整件事。也许X应该是一个注册了Y的服务器…当y找不到x时,这不是真正的问题。但是x找不到y不能导致延迟或其他问题…

    9 回复  |  直到 15 年前
        1
  •  5
  •   Ken White    15 年前

    你可以做得更简单,因为你只是想知道一个应用是否从另一个应用运行。只要它们在同一台机器上由同一个用户运行,就可以让X简单地使用 FindWindow ()查看Y当前是否正在运行。只需确保给你一个有意义的名字(在下面的示例中,它是txmlformatterform):

    var
      XMLWindow: HWnd;
    begin
      XMLWindow := FindWindow('TXMLFormatterForm', nil);
      if XMLWindow > 0 then
        // Y is running
    end;
    

    您也可以使用Y的窗口标题(标题),只要您确定它是不同的:

    XMLWindow := FindWindow(nil, 'Workshop Alex's XML Formatter');
    
        2
  •  11
  •   Runner    15 年前

    请看一下我的工控机:

    http://www.cromis.net/blog/downloads/cromis-ipc/

    它速度快、免费并且有一个可设置的超时,所以您可以将其设置为非常小的量(例如50毫秒)。因为它非常快(典型的消息周期请求-处理-响应时间不到1毫秒,大约0.1毫秒),所以您可以有非常小的超时。它内置了客户机-服务器,所以许多客户机都没有问题。它以线程的方式运行,后面有任务池,这样它就不会冻结您的程序,并且它有非常灵活的数据包,以便于写入/读取数据。

    如前所述,如果调试器正在运行,您甚至可以使用其他方法进行检查。

    • 检查流程
    • 检查进程的主窗口
    • 使用互斥体
        3
  •  6
  •   Steve Townsend    15 年前

    你可以让x把它的输出写到 memory-mapped file -如果正在运行,Y可以检索数据。这样x不关心y是否向上。

    X可以在已知位置写入某种控制信息(例如,在映射文件中存储最近1000个从偏移量0开始写入的XML的偏移量),并将文件的其余部分用作原始数据的循环缓冲区。

    如果需要y作为x中动作的决定因素,请让y创建映射文件,然后使用其存在/不存在作为“通道”x侧数据生成的检查。有创建者和第二个用户的示例代码 here .

        4
  •  4
  •   Community Mohan Dere    9 年前

    命名管道很快,因为它们是基于内存映射文件来实现的。如果服务器出现故障,超时可能会变慢…

    如果您需要在同一台计算机上有快速响应,为什么不使用好的旧GDI消息?

    您可以在纯控制台或后台服务应用程序(对于服务应用程序,安全设置必须指定此服务必须与桌面交互,即必须能够接收和发送消息)中使用这些消息,即使没有用户界面或视觉形式。

    诀窍是处理wm_CopyData消息。 例如,请参见tsqlrestclienturimessage类和tsqlrestserver的exportservermessage/answertomessage方法,如中所实现的 http://synopse.info/fossil/finfo?name=SQLite3/SQLite3Commons.pas

    在实践中,我发现对于少量数据(每个消息高达64KB或类似的大小),GDI消息比命名管道快得多。

    你还有其他选择 Looking for an alternative to windows messages used in inter-process communication

        5
  •  2
  •   A.Bouchez    15 年前

    根据不同的客户机/服务器调查,这里有一些关于速度的真实数据。

    所有基准测试都在一台计算机上本地运行。您可以在直接访问上每秒实现超过15000个查询,在HTTP/1.1远程访问上每秒实现4300个查询。这是一个使用Centrino2 CPU的笔记本电脑的基准测试,防病毒软件处于开启状态。

    2.5. Client server access: 
      - Http client keep alive: 3001 assertions passed
         first in 7.87ms, done in 153.37ms i.e. 6520/s, average 153us
      - Http client multi connect: 3001 assertions passed
         first in 151us, done in 305.98ms i.e. 3268/s, average 305us
      - Named pipe access: 3003 assertions passed
         first in 78.67ms, done in 187.15ms i.e. 5343/s, average 187us
      - Local window messages: 3002 assertions passed
         first in 148us, done in 112.90ms i.e. 8857/s, average 112us
      - Direct in process access: 3001 assertions passed
         first in 44us, done in 41.69ms i.e. 23981/s, average 41us
      Total failed: 0 / 15014  - Client server access PASSED
    

    这个基准测试客户机和服务器的速度,并且不是多线程的(即使我们的框架是多线程安全的)。

    因此,您可以猜测,对于每个请求的4kb JSON内容数据块:

    1. 直接访问(像您的DLL方法)是最快的,而且资源消耗更少。
    2. 然后是GDI消息。
    3. 然后命名管道。
    4. 然后是FastCGI和HTTP(取决于您的Web服务器对FastCGI的使用情况,HTTP类的使用量非常低)。

    http://synopse.info/forum/viewtopic.php?id=90

        6
  •  1
  •   Eugene Mayevski 'Callback    15 年前
        7
  •  1
  •   skamradt    15 年前

        8
  •  0
  •   APZ28    15 年前

        9
  •  0
  •   g19fanatic    15 年前

    推荐文章