代码之家  ›  专栏  ›  技术社区  ›  miked

跨平台双向工控机

  •  2
  • miked  · 技术社区  · 17 年前

    我有一个项目,我认为这将是相对容易的,但结果是更痛苦的,我希望。首先,我与之交互的大多数代码都是我无法控制的遗留代码,因此我无法进行重大的范式更改。

    我想做的是编写一个应用程序,它可以启动一系列这些简单的程序,监视事件,然后根据需要向它们发送命令。我最初的计划是使用类似popen的东西,但我需要一个双向popen来获得读和写管道。我把一些东西拼凑在一起,我称之为popen2,在这里我给它传递要运行的命令和两个文件*,其中充满了读写流。然后我需要做的就是编写一个简单的循环,从每个进程的每个标准输出读取数据,执行它需要的逻辑,然后将命令写回正确的进程。

    这里有一些伪代码

    FILE *p1read, *p1write;
    FILE *p2read, *p2write;
    FILE *p3read, *p3write;
    
    //start each command, attach to stdin and stdout
    popen2("process1",&p1read,&p1write);
    popen2("process2",&p2read,&p2write);
    popen2("process3",&p3read,&p3write);
    
    while (1)
    {
       //read status from each process
       char status1[1024];
       char status2[1024];
       char status3[1024];
       fread(status1,1024,p1read);
       fread(status2,1024,p2read);
       fread(status3,1024,p3read);
    
       char command1[1024];
       char command2[1024];
       char command3[1024];
       //do some logic here
    
       //write command back to each process
       fwrite(command1,p1write);
       fwrite(command2,p2write);
       fwrite(command3,p3write);
    }
    

    真正的程序更复杂,它在流中查看是否有任何东西在等待,如果没有,它将跳过该进程,同样,如果它不需要向某个进程发送命令,它也不需要。但这段代码给出了基本思想。

    困难的部分是,我的popen2使用fork()和execl()启动进程,并将流分配给子进程的stdin和stdout。有没有一种干净的方法可以在windows中执行此操作?基本上,我想创建一个popen2,它在windows中的工作方式与我的unix版本相同。这样,该函数中就只有特定于windows的代码,其他所有代码都可以以同样的方式工作。

    有什么想法吗?

    谢谢

    2 回复  |  直到 17 年前
        1
  •  6
  •   Martin v. Löwis    17 年前

    在Windows上,首先调用CreatePipe(类似于管道(2)),然后调用CreateProcess。这里的技巧是CreateProcess有一个参数,您可以在其中传递新创建的进程的stdin、stdout、stderr。

    请注意,当您使用stdio时,需要执行fdopen来创建文件对象,该对象需要文件号。在Microsoft CRT中,文件编号与操作系统文件句柄不同。因此,要将CreatePipe的另一端返回给调用者,首先需要_open_osfhandle获取CRT文件号,然后fdopen。

    http://svn.python.org/view/python/trunk/Modules/posixmodule.c?view=markup

        2
  •  0
  •   Jonathan Leffler    17 年前

    我认为,通过使用popen2()函数抽象出跨平台问题,您已经为您的问题提供了一个很好的开端。我本想来建议“插座”,但我相信在阅读了问题后,这与此无关。您可以使用套接字而不是管道-它将隐藏在popen2()函数中。

    我99%确信您可以使用Windows API在Windows上实现所需的功能。我不能做的是给你指出正确的函数。但是,您应该知道,Microsoft提供了大多数类似于POSIX的API调用,但是名称的前缀是“389;”。还有一些本机API调用可以实现 fork 和 exec .

    您的评论表明,您已意识到数据可用性问题和可能的死锁——请谨慎。