如何使其与Windows兼容?

时间:2010-08-13 13:41:32

标签: python pipe subprocess portability

美好的一天,Stackoverflow!

将Linux的一个Python脚本移植到Windows时,我遇到了一个小问题。关于这一点的毛茸茸的事情是我必须启动一个进程并将其所有流重定向到管道中,我在脚本中读取和写入和写入。

使用Linux,这是小菜一碟:

server_startcmd = [
           "java", 
           "-Xmx%s" % self.java_heapmax, 
           "-Xms%s" % self.java_heapmin,
           "-jar",
           server_jar,
           "nogui"
        ]

server = Popen(server_startcmd, stdout = PIPE, 
                                stderr = PIPE, 
                                stdin  = PIPE)

outputs = [
     server_socket, # A listener socket that has been setup before
     server.stderr,
     server.stdout,
     sys.stdin # Because I also have to read and process this.
   ]

clients = []

while True:
     read_ready, write_ready, except_ready = select.select(outputs, [], [], 1.0)

     if read_ready == []:
        perform_idle_command() # important step
     else:
        for s in read_ready:
           if s == sys.stdin:
              # Do stdin stuff
           elif s == server_socket:
              # Accept client and add it to 'clients'
           elif s in clients:
              # Got data from one of the clients

整个3路在服务器套接字,脚本的stdin和子进程的输出通道(以及输入通道)之间交替,因为我的脚本会写入那个,尽管那个不在select中()list)是脚本中最重要的部分。

我知道对于Windows,win32api模块中有win32pipe。问题是找到这个API的资源非常困难,我发现的并不是真的有用。

如何利用这个win32pipe模块做我想做的事情?我有一些消息来源,它用于不同但相似的情况,但这让我非常困惑:

if os.name == 'nt':
   import win32pipe
  (stdin, stdout) = win32pipe.popen4(" ".join(server_args))
else:
   server = Popen(server_args,
     stdout = PIPE,
     stdin = PIPE,
     stderr = PIPE)
   outputs = [server.stderr, server.stdout, sys.stdin]
   stdin = server.stdin

[...]

while True:
   try:
      if os.name == 'nt':
         outready = [stdout]
      else:
         outready, inready, exceptready = select.select(outputs, [], [], 1.0)
   except:
      break

stdout这里是以win32pipe.popen4(...)

开头的子进程的组合stdout和stderr

问题是:

  • 为什么不是select()的Windows版本?这不起作用吗?
  • 如果你不在那里使用select(),我怎样才能实现select()提供的必要超时(显然这里不会像这样工作)

请帮帮我!

1 个答案:

答案 0 :(得分:0)

我认为你不能在管道上使用select()。 在其中一个项目中,我将Linux应用程序移植到Windows上,我也错过了这一点,不得不重写整个逻辑。