Как мне сделать это совместимым с Windows? - PullRequest
1 голос
/ 13 августа 2010

Добрый день, Stackoverflow!

У меня небольшая (большая) проблема с переносом одного из моих скриптов Python для Linux на 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 способа чередуются между сокетом сервера, стандартным сценарием сценария и выходными каналами дочернего процесса (а также входным каналом, поскольку мой сценарий будет записывать в него, хотятот, которого нет в списке select (), является самой важной частью скрипта.

Я знаю, что для 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 вот комбинированный stdout и stderr дочернего процесса, который был запущен сwin32pipe.popen4(...)

Возникают следующие вопросы:

  • Почему бы не select() для версии Windows?Разве это не работает?
  • Если вы не используете select() там, как я могу реализовать необходимый тайм-аут, который предоставляет select() (который, очевидно, не будет работать здесь)

Пожалуйста, помогите мне!

1 Ответ

0 голосов
/ 03 сентября 2010

Я думаю, что вы не можете использовать select () для каналов.В одном из проектов, где я переносил приложение linux на Windows, я тоже упустил этот момент и должен был переписать всю логику.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...