[comp.unix.wizards] SYS V Rel 3.2

pryor@uunet.UUCP (Paul Pryor) (02/14/90)

This seem to be so simple a question, but I could not resolve it, even
after reading every RTFM's I could find anywhere !

I ran into a serious flaw in SYSV Rel 3.2, if it could be called a flaw
(probably never would be the last one !). Here's my simple problem:

	creates two pipes, called pipea & pipeb using pipe(2)
	forked using fork(2)

	child dups (using dup2(3)) pipea with stdout, pipeb with stdin
	child execl's a program (now a background process)

	parent sets pipea & stdin to O_NDELAY by using fcntl(2).
	parent goes into a busy loop
		read from pipea using read(2). If there are bytes
		returned from read(), it writes them out to stdout

		read from stdin using read(2). If there are bytes
		returned from read(), it writes them out to pipeb

From above algorithm, I immediately ran into two serious problems:

a) the read(2) call, if pipe is empty, but not closed, returns -1. Since
I'm on SYS V Rel 3, I'm really stuck ! Does SYS V Rel 4 fixes this little
itty bitty problem ? I, instead, depended on stdin being closed as the
indication when to terminate and break out of the busy loop. This worked
well enough.

b) the biggest and worst problem is that I had to go into a busy loop
reading from two asyncronous input sources ! The signal(2) man page
says that SIGPOLL is used only with STREAMS. And I don't want to get
really mixed up with IPC's pipes. They are not as well documented as
I would like them to. And same goes for STREAMS, and I don't even
know if I could implement pipes roughly using STREAMS thanks to lack
of documentations I have on hand.

I didn't want to put in sleep()'s because I wanted to create time stamps
for groups of bytes read in from either sources.

Right now the program as described above works, but its a veritable cpu
hog. Running multiple instances of the same program immediately brought
AT&T 3B2/600G down to its knees.

How do I find my way out of this predicatement ?

Thanks, guys & gals !!!

Paul.
-- 
Paul T. Pryor (uunet!imspw6!pryor)
Integrated Microcomputer Systems, INC. Rockville, MD

peter@ficc.uu.net (Peter da Silva) (02/21/90)

Alas, System V is missing any way of doing this.

BSD lets you do this, but not very cleanly.

We just got through a discussion on this subject. What's needed is a set
os asynchronous equivalents to read/write that return a token you can wait
on.
-- 
 _--_|\  Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \
\_.--._/ Xenix Support -- it's not just a job, it's an adventure!
      v  "Have you hugged your wolf today?" `-_-'

les@chinet.chi.il.us (Leslie Mikesell) (02/22/90)

In article <244@imspw6.uunet.UUCP> pryor@uunet.UUCP (Paul Pryor) writes:

>		read from pipea using read(2). If there are bytes
>		returned from read(), it writes them out to stdout

>		read from stdin using read(2). If there are bytes
>		returned from read(), it writes them out to pipeb

>From above algorithm, I immediately ran into two serious problems:

Why not fork another process for one of these jobs?  Then you can
forget the O_NDELAY stuff and let the read()'s block when there is
nothing to do and stop hogging the CPU. 

>I didn't want to put in sleep()'s because I wanted to create time stamps
>for groups of bytes read in from either sources.

A one second sleep() in the busy loop will make the difference between
about 4 syscalls/sec (no real problem) and the hundreds (all the CPU
can handle) that you get without it.  If you need < 1 sec. granularity
then you can either run two processes or find a way to block for a 
shorter time.  Some SysV's have nap(), or you could play games with
a read() on an unused ttyline with VMIN/VTIME set appropriately - or if
stdin happens to be a tty you can do it directly.

Les Mikesell
  les@chinet.chi.il.us