蟒蛇os.mkfifo()用于Windows

问题描述:

短版(如果你能回答的短版它确实为我工作,其余主要是为其他人有类似的任务受益):蟒蛇os.mkfifo()用于Windows

在蟒蛇在Windows中,我要创建2个文件对象,连接到同一个文件(它不必是硬盘驱动器上的实际文件),一个用于读取,一个用于写入,这样,如果读取结束尝试阅读它永远不会得到EOF(它会阻止,直到写入东西)。我认为在linux os.mkfifo()会做这项工作,但在Windows中它不存在。可以做什么? (我必须使用文件对象)。

一些额外的细节: 我有一个python模块(不是我写的)通过stdin和stdout(使用raw_input()和print)来玩特定的游戏。我也有一个Windows可执行文件通过stdin和stdout来玩同一个游戏。我想让他们互相对抗,并记录他们所有的交流。

这是我能写的代码(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 
+0

你试图放弃'get_fifo()'和'连接与pythonmodule'的Windows可执行文件直接:'SYS。 stdin,sys.stdout = p1.stdout,p1.stdin'。一切''通过pythonmodule' print'ed写入'p1.stdin'和的raw_input'()''从p1.stdout'在这种情况下读取。如果由于Python端的缓冲问题而失败;尝试使用无缓冲标准输入/输出运行脚本:'蟒蛇-u your_script.py'并添加'BUFSIZE = 0'参数'Popen'。 – jfs 2013-12-20 11:15:10

遵循上述两个答案,我不小心撞到了答案。 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.source.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]) 
+3

+1自我回答适合于计算器 – msw 2010-05-27 16:20:12

在Windows上,你在看(Named or Anonymous) Pipes

管道是处理用于通信的共享内存的一部分。创建管道的过程是管道服务器。连接到管道的进程是管道客户端。一个进程将信息写入管道,然后另一个进程从管道读取信息。

要使用Windows管道的工作,你可以使用Python for Windows extensions (pywin32),或Ctypes module。一个特殊的实用程序模块win32pipe提供了一个到win32管道API的接口。它包括popen[234]()便利功能的实现。

how-to-use-win32-apis-with-python和SO类似的问题(不是特定于管道,但点有用的信息)。

+0

所以,....为什么地球上不能蟒蛇只是代码复制粘贴到自己的mkfifo功能? – 2017-10-22 23:45:01

对于跨平台的解决方案,我建议在localhost(127.0.0.1)上的套接字之上构建类文件对象 - 这是IDLE默认可以解决与您的问题非常相似的问题。

+0

好主意!当TCP套接字完全相同时,无需使用管道。 – user1495323 2015-07-13 01:09:35