If this isn't exactly what you wanted, please try our Search (there's a LOT of techy and non-techy stuff here about Linux, Unix, Mac OS X and just computers in general!):
From: email@example.com (Grant Edwards) Newsgroups: comp.os.linux.misc Subject: Re: I/O in application programs. References: <39EB25B2.53748B60@yahoo.com> Message-ID: <V7KG5.1515$FU3.firstname.lastname@example.org> Date: Mon, 16 Oct 2000 21:09:09 GMT In article <39EB25B2.53748B60@yahoo.com>, Fred wrote: >In section 12.5 of his book, Stevens treats the topic of "I/O >Multiplexing." Therein Stevens carefully cautions his reader >that "I/O multiplexing is not yet part of POSIX." In other >words, reference to the POSIX specification will not answer my >questions. I must determine how things work in the real world. >And because I wish to maximize the portability of my program, I >must not limit my inquiry to the workings of my specific Unix >platform. Rather, I must try to learn how most Unix platforms >do this kind of work.
I don't think that Unix applications typically try to overlap input/compute/output. [ regarding select ] >the descriptors that are ready." From his remarks, I gather >that the select function will (optionally) suspend execution >of the application program until such moment as there is a >change in one or more of these bits. Correct. >So far, so good. I say this because, although the above-quoted >passages may appear cryptic when lifted out of context (as I >have done), they are clear enough when read in combination with >other things Stevens says about I/O multiplexing. The problem >comes a couple of paragraphs later, where he says, "We now need >to be more specific about what 'ready' means." Stevens then >proceeds to define "ready" so that the word has no genuine >meaning. He says, for instance, that "A descriptor in the >write set is considered ready if a write to that descriptor >won't block." If you're taling about regular file I/O, files are _always_ ready in Unix. Using select on a file-descriptor that is associated with a regular file is not a useful thing to do.
File-descriptors associated with things like TCP connections and serial ports may be not-ready, and select is useful for them. >In passing, I wonder how the kernel can know for sure that a >future I/O operation won't block, without knowing the details >of the operation. It can't. If you try to write a block of data larger than can be buffered, and you've got non-blocking I/O enabled, then the driver will take as much as it can. You have to look at the return value of write() to see how much data was actually "consumed" by the driver. If you try to read more data than available from a non-blocing descriptor then it will give you however much it has available. You've got to check the return value from read() to see how many bytes you received. NB: A file descriptor is "ready" if there is at least 1 byte of data to be read, or room for at least 1 byte of data. (Or there's an error, or it's close, or ....). >No doubt it is nice to know that the next call to write >will not block, but that's not the same as knowing that the >previous call to write is finished. How do you define "finished?" Generally, you just leave the file-descriptors in blocking mode and don't worry about it -- read() won't return until it's read as much data as you requested, and write() won't return until it's written all of the data you gave it. >Similarly it is nice to know that the next call to read will >not block, but that's not the same as knowing that the previous >call to read is finished, and much less is it the same as >knowing that the read did not encounter an EOF condition. In >other words, the select function offers a prediction about the >future, but that is not what I need at steps 3, 8, and 12. What >I need is not a prediction about the future, but rather a >statement about the present. For example, when my program >arrives at step 3, either the input operation is finished, or >it's not. If it's finished, I can safely copy data from the >input buffer to the computational buffer. If it's not >finished, I need to go to sleep until such time as it is >finished. Apparently, neither select nor poll meets this need. Unless you're writing a multi-threaded program, the easiest thing to do is leave the descriptors in non-blocking mode read(), compute(), write(). read() and write() both return the number of bytes read/written. If you really want to overlap the read/compute/write operations, you're going to have to have multiple threads. In that case, use blocking read/write calls in the I/O threads and and semaphores for inter-thread synchronisation. I'd recommend that you become proficient at single-threaded Unix application programming before you try to do a multiple-threaded implimentation. -- Grant Edwards grante Yow! I'm using my X-RAY at VISION to obtain a rare visi.com glimpse of the INNER WORKINGS of this POTATO!!
Got something to add? Send me email.
I just had to take the hypertext idea and connect it to the TCP and DNS ideas and — ta-da!— the World Wide Web. ((Tim Berners-Lee)