473,378 Members | 1,475 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Pipe IO Problem?

A wrote a small class to handle IO through pipes, but the connection
only seems to work in one direction. The following code defines
connection.py, engine.py, and controller.py. Once connected, the engine
is only able to send and the controller recieve. Also, this only works
when using popen2.popen3. Using os.popen3 doesn't work at all and seems
to behave completely differently.
What could be causing these problems? Any help is greatly appreciated.

##-------------------------------------------
# connection.py
import sys
import threading
import socket
import time

class ConnectionError(Exception):
'''Encapsulates connection errors.'''
pass

class Connection:
'''Base class for an interprocess connection.

This class is meant to be used in two primary ways:
First, as a caller, the initiator of the connection.
Second, as a callee, the recepiant of the connection.

However, once the connection has been made, general use should
behave symmetrically.'''

def __init__(self, in_handler=None):
self.connected = False
self._recv_handler = in_handler
self._recv_buffer = [] # stores data if no in_handler given
self._recv_lock = threading.Lock()
self._send_lock = threading.Lock()

def _send_raw(self, string):
'''Outgoing handler.'''
raise Exception, 'this method must be overridden'

def _recv_raw(self):
'''Incoming handler.'''
raise Exception, 'this method must be overridden'

def _launch_recv_handler(self):
'''Launches general reception handler.'''
assert not self.connected, 'connection already open'
print 'launching recv handler'
self.connected = True
t = threading.Thread(target=self._recv_raw)
t.setDaemon(True)
t.start()

def _launch_data_handler(self, data):
'''Launches user defined reception handler.'''

if self._recv_handler: # launch custom handler (ie in_handler)
if present
t = threading.Thread(target=self._recv_handler, args=(data,))
t.setDaemon(True)
t.start()
else: # otherwise append to buffer
self._recv_lock.acquire()
self._recv_buffer.append(data)
self._recv_lock.release()

def open(self):
raise Exception, 'this method must be overridden'

def close(self, message=None):
raise Exception, 'this method must be overridden'

def send(self, data):
assert self.connected, 'not connected'
self._send_raw(data)

def recv(self):
'''Blocks until it has data to return.
Only use this if you haven't specified a reception handler.'''
assert self.connected, 'not connected'

# wait for data
while not len(self._recv_buffer):
time.sleep(0.1)

# get data
self._recv_lock.acquire()
data = self._recv_buffer.pop(0)
self._recv_lock.release()

return data

def pending(self):
'''True if pending data in the buffer. False otherwise.'''
return bool(len(self._recv_buffer))

def name(self):
pass

class Pipe(Connection):
'''Base class for a pipe connection.'''

def __init__(self, *args, **kargs):
Connection.__init__(self, *args, **kargs)

def _send_raw(self, string):
assert self.connected, 'not connected'

try:
self._send_lock.acquire()
self._outp.write(string+'\n')
self._outp.flush()
self._send_lock.release()
except Exception, e:
self._send_lock.release()
self.close(e)
raise Exception, e

def _recv_raw(self):

while self.connected:
# get data
try:
data = self._inp.readline()
except Exception, e:
self.close(e)
break
if not len(data):
time.sleep(0.1)
continue

# launch handler
self._launch_data_handler(data)

def open(self, target=None):
assert not self.connected, 'connection already open'

if target:
#import os # different functionality?
#(self._inp, self._outp, self._errp) = os.popen3(target)
import popen2
(self._inp, self._outp, self._errp) = popen2.popen3(target)
else:
from sys import stdin, stdout
self._inp = stdin
self._outp = stdout

self._launch_recv_handler()

def close(self, message=None):
assert self.connected, 'connection already closed'

self.connected = False
self._inp.close()
self._inp = None
self._outp.close()
self._outp = None
self._errp.close()
self._errp = None

if message:
print message
##-------------------------------------------
# engine.py
import time

from connection import *

outfile = open('enginetest.data', 'w')

def print_received(data):
print >>outfile, data

conn = Pipe(in_handler=print_received)
conn.open()

for i in range(5):
time.sleep(1)
conn.send('engine '+str(i))

outfile.close()
##-------------------------------------------
# controller.py
import time

from connection import *

def print_received(data):
print 'controller received:',data

conn = Pipe(in_handler=print_received)
conn.open('pipetest_engine.py')

for i in range(5):
print 'controller',i
time.sleep(1)
conn.send(str(i))
Jul 18 '05 #1
1 2277
In article <A5X_c.5607$wF4.1948@trndny09>,
"Chris S." <ch*****@NOSPAM.udel.edu> wrote:
A wrote a small class to handle IO through pipes, but the connection
only seems to work in one direction. The following code defines
connection.py, engine.py, and controller.py. Once connected, the engine
is only able to send and the controller recieve. Also, this only works
when using popen2.popen3. Using os.popen3 doesn't work at all and seems
to behave completely differently.


I'm too lazy to track down the problem in your code, but
os.popen3 vs. popen2.popen3 is an easy one. You can see
the code yourself, in the os.py module --

def popen3(cmd, mode="t", bufsize=-1):
import popen2
stdout, stdin, stderr = popen2.popen3(cmd, bufsize)
return stdin, stdout, stderr

Note different return value.

You can avoid some confounding factors, and possibly the
need for a separate thread, if you use the UNIX file descriptors
(e.g., outpfd = outp.fileno(), os.write(outpfd, string + '\n'),
etc. The thread could go away if select() turns out to be suitable
for your application. The buffering you get with file objects
is relatively useless here and likely not worth the trouble it causes.

Donn Cave, do**@u.washington.edu
Jul 18 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Frank de Bot | last post by:
Hi, occasionaly I find in my apache logs that fastcgi had a broken pipe error with php running as fastcgi. the logs are like this: -- > (32)Broken pipe: > FastCGI: comm with server...
2
by: Doug | last post by:
This works with a small string, but not a large one (read returns an empty string if i pass a large html file to tidy): >>> iin , iiout = popen2("tidy.exe -asxml") >>> iin.write(str) >>>...
1
by: Brad Murdoch | last post by:
im trying to run the select.selct() on a unix pipe, my expectation is that it will block untill there is something there to read, then continue. It seems to do this untill the pipe is written to...
5
by: richard | last post by:
I have a simple test to pass information from a client to a server using named pipe. what I really want is: when I type a line on the client, the server will output the line immediately. but to my...
7
by: Greg | last post by:
I am trying to implement the UNIX pipe command using C but with the "->" operator. Everything works fine with 1 pipe, but when I try to use 2 or more, it hangs up when reading the pipe_in...
2
by: FB's .NET Dev PC | last post by:
I am writing two services in VB.NET, one of which needs to send text strings to the other. After reading, I decided (perhaps incorrectly) that named pipes would be the best interprocess...
1
by: David Reed | last post by:
Is there any way to have one program run another arbitrary program with input from stdin and display the output as if you had run it in a shell (i.e., you'd see some of the output followed by the...
0
by: olaf.dietsche | last post by:
Hi, The system is Windows XP and DB2 v8.1.7. I'm trying to load a text file via named pipe into a table. I have two programs: the first program creates the named pipe, waits for a client...
2
by: Steve R. Hastings | last post by:
While studying iterators and generator expressions, I started wishing I had some tools for processing the values. I wanted to be able to chain together a set of functions, sort of like the...
2
by: Dhika Cikul | last post by:
Hello, I'm new in Python, i don't know my subject is correct or wrong. I have problem with my script. I want to change password with passwd password in python without user submitted anything...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.