4

短いバージョン(短いバージョンに答えることができれば、それは私のために仕事をします、残りは主に同様の仕事をしている他の人々の利益のためです):

WindowsのPythonで、同じファイルに添付された2つのファイルオブジェクトを作成したい(ハードドライブ上の実際のファイルである必要はありません).1つは読み取り用、もう1つは書き込み用で、読み取りが終了した場合読み取ろうとしても EOF を取得しません (何かが書き込まれるまでブロックされます)。Linux では os.mkfifo() が機能すると思いますが、Windows では存在しません。何ができるでしょうか?(ファイルオブジェクトを使用する必要があります)。

いくつかの追加の詳細: stdin と stdout (raw_input() と print を使用) を介して特定のゲームをプレイする python モジュール (私が作成したものではありません) があります。stdin と stdout を介して、同じゲームをプレイする Windows 実行可能ファイルもあります。私は彼らに対戦させて、彼らのすべてのコミュニケーションを記録したいと思っています。

これが私が書くことができるコードです(get_fifo()Windowsでそれを行う方法がわからないため、関数は実装されていません):

class Pusher(Thread):
        def __init__(self, source, dest, p1, name):
                Thread.__init__(self)
                self.source = source
                self.dest = dest
                self.name = name
                self.p1 = p1

        def run(self):
                while (self.p1.poll()==None) and\
                      (not self.source.closed) and (not self.source.closed):
                        line = self.source.readline()
                        logging.info('%s: %s' % (self.name, line[:-1]))
                        self.dest.write(line)
                        self.dest.flush()


exe_to_pythonmodule_reader, exe_to_pythonmodule_writer =\
                          get_fifo()
pythonmodule_to_exe_reader, pythonmodule_to_exe_writer =\
                          get_fifo()

p1 = subprocess.Popen(exe, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)

old_stdin = sys.stdin
old_stdout = sys.stdout

sys.stdin = exe_to_pythonmodule_reader
sys.stdout = pythonmodule_to_exe_writer

push1 = Pusher(p1.stdout, exe_to_pythonmodule_writer, p1, '1')
push2 = Pusher(pythonmodule_to_exe_reader, p1.stdin, p1, '2')

push1.start()
push2.start()
ret = pythonmodule.play()
sys.stdin = old_stdin
sys.stdout = old_stdout
4

4 に答える 4

16

上記の2つの答えに続いて、私は誤って答えにぶつかりました。os.pipe()がその役割を果たします。ご回答ありがとうございます。

他の誰かがこれを探している場合に備えて、私は完全なコードを投稿しています:

import subprocess
from threading import Thread
import time
import sys
import logging
import tempfile
import os

import game_playing_module

class Pusher(Thread):
    def __init__(self, source, dest, proc, name):
        Thread.__init__(self)
        self.source = source
        self.dest = dest
        self.name = name
        self.proc = proc

    def run(self):
        while (self.proc.poll()==None) and\
              (not self.source.closed) and (not self.dest.closed):
            line = self.source.readline()
            logging.info('%s: %s' % (self.name, line[:-1]))
            self.dest.write(line)
            self.dest.flush()

def get_reader_writer():
    fd_read, fd_write = os.pipe()
    return os.fdopen(fd_read, 'r'), os.fdopen(fd_write, 'w')

def connect(exe):
    logging.basicConfig(level=logging.DEBUG,\
                        format='%(message)s',\
                        filename=LOG_FILE_NAME,
                        filemode='w')

    program_to_grader_reader, program_to_grader_writer =\
                              get_reader_writer()

    grader_to_program_reader, grader_to_program_writer =\
                              get_reader_writer()

    p1 = subprocess.Popen(exe, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)        

    old_stdin = sys.stdin
    old_stdout = sys.stdout

    sys.stdin = program_to_grader_reader
    sys.stdout = grader_to_program_writer

    push1 = Pusher(p1.stdout, program_to_grader_writer, p1, '1')
    push2 = Pusher(grader_to_program_reader, p1.stdin, p1, '2')

    push1.start()
    push2.start()

    game_playing_module.play()

    sys.stdin = old_stdin
    sys.stdout = old_stdout

    fil = file(LOG_FILE, 'r')
    data = fil.read()
    fil.close()
    return data

if __name__=='__main__':
    if len(sys.argv) != 2:
        print 'Usage: connect.py exe'
        print sys.argv
        exit()
    print sys.argv
    print connect(sys.argv[1])
于 2010-05-27T16:17:34.517 に答える
6

Windows では、(Named or Anonymous) Pipesを見ています。

パイプは、プロセスが通信に使用する共有メモリのセクションです。パイプを作成するプロセスがパイプ サーバーです。パイプに接続するプロセスは、パイプ クライアントです。一方のプロセスがパイプに情報を書き込み、もう一方のプロセスがパイプから情報を読み取ります。

Windows Pipes を操作するには、 Python for Windows extensions (pywin32)またはCtypes モジュールを使用できます。特別なユーティリティ モジュールwin32pipeは、win32 パイプ API へのインターフェイスを提供します。popen[234]()これには、便利な関数の実装が含まれています。

how-to-use-win32-apis-with-pythonおよび同様の SO の質問を参照してください(パイプに固有のものではありませんが、役立つ情報を示しています)。

于 2010-05-27T15:20:28.023 に答える
5

クロスプラットフォーム ソリューションの場合、localhost (127.0.0.1) のソケットの上にファイルのようなオブジェクトを構築することをお勧めします。これは、IDLE がデフォルトで行うことで、あなたの問題に非常によく似ています。

于 2010-05-27T15:20:40.000 に答える