|
Home > Archive > Unix Programming > October 2005 > open FIFO blocking with select - high CPU
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
open FIFO blocking with select - high CPU
|
|
| dhanks@gmail.com 2005-10-29, 2:49 am |
| Hi All,
I've open(2)ed a FIFO and I'm blocking. I use select(2) to detect if
there is data to read(2).
I tested my FIFO brain puzzle with:
$ cat /dev/zero > /tmp/FIFO
Which should really put it to work. My problem is that my program is
using a lot of CPU after I ^C the cat /dev/zero and the program is
doing nothing but sleeping (blocking) on the select(2). I've also
placed a ticker above the select(2) to visually ensure that the program
isn't in an infinite loop.
Again, just to clarify: I understand the the program should use a lot
of CPU while it is read(2)ing from my stress test with cat /dev/zero,
but _after_ I have ^C the cat, so that the program is doing nothing at
all and awaiting more things to read(2), it continually shows high CPU
usage with ps aux - but the CPU grandually goes back down to normal.
-----BEGIN EXAMPLE-----
$ cat /dev/zero > /tmp/FIFO
^C
$ ps aux|grep fifo
dhanks 31574 8.9 0.1 1348 280 pts/1 S 22:07 0:04 ./fifo
dhanks 31581 0.0 0.2 3576 632 pts/0 S 22:08 0:00 grep
fifo
$ ps aux|grep fifo
dhanks 31574 8.2 0.1 1348 280 pts/1 S 22:07 0:04 ./fifo
dhanks 31583 0.0 0.2 3568 628 pts/0 S 22:08 0:00 grep
fifo
$ ps aux|grep fifo
dhanks 31574 7.6 0.1 1348 280 pts/1 S 22:07 0:04 ./fifo
dhanks 31585 0.0 0.2 3568 628 pts/0 S 22:08 0:00 grep
fifo
$
-----END EXAMPLE-----
Any suggestions are welcome.
Code follows.
-----BEGIN CODE-----
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FIFO "/tmp/FIFO"
#define finit(x) x.fd = -1; \
x.n = -1; \
x.in.bytes = 0; \
x.in.packets = 0; \
x.out.bytes = 0; \
x.out.packets = 0; \
memset(x.buffer, '\0', sizeof(x.buffer));
struct s_io
{
unsigned long int bytes;
unsigned int packets;
} io;
struct s_file
{
int fd;
int n;
struct s_io in;
struct s_io out;
char buffer[2048];
} file;
int main(int argc, char *argv[])
{
struct s_file f;
finit(f);
if((f.fd = open(FIFO, O_RDONLY)) == -1)
{
fprintf(stderr, "open: %.100s: %.100s (%i)\n", FIFO,
strerror(errno), errno);
exit(EXIT_FAILURE);
}
while(1)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(f.fd, &fds);
fprintf(stderr, "#");
if(select(f.fd + 1, &fds, NULL, NULL, NULL) == -1)
{
if(errno == EINTR)
continue;
fprintf(stderr, "select: %.100s (%i)\n",
strerror(errno), errno);
close(f.fd);
exit(EXIT_FAILURE);
}
memset(f.buffer, '\0', sizeof(f.buffer));
if(FD_ISSET(f.fd, &fds))
{
if((f.n = read(f.fd, f.buffer, sizeof(f.buffer)
- 1)) <= 0)
{
switch(f.n)
{
case 0:
fprintf(stderr, "%lu
bytes\n", f.in.bytes);
if(close(f.fd) == -1)
{
fprintf(stderr,
"close: %.100s: %.100s (%i)\n", FIFO, strerror(errno), errno);
exit(EXIT_FAILURE);
}
finit(f);
if((f.fd = open(FIFO,
O_NONBLOCK)) == -1)
{
fprintf(stderr,
"open: %.100s: %.100s (%i)\n", FIFO, strerror(errno), errno);
exit(EXIT_FAILURE);
}
break;
default:
fprintf(stderr, "read:
%.100s (%i)\n", strerror(errno), errno);
close(f.fd);
exit(EXIT_FAILURE);
break;
}
}
f.in.bytes += f.n;
f.in.packets++;
}
else
{
fprintf(stderr, "FD_ISSET: f.fd isn't set:
%.100s (%i)\n", strerror(errno), errno);
close(f.fd);
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
-----END CODE-----
| |
| Alex Fraser 2005-10-29, 5:51 pm |
| <dhanks@gmail.com> wrote in message
news:1130563913.318686.37090@g14g2000cwa.googlegroups.com...
> I've open(2)ed a FIFO and I'm blocking. I use select(2) to detect if
> there is data to read(2).
>
> I tested my FIFO brain puzzle with:
>
> $ cat /dev/zero > /tmp/FIFO
>
> Which should really put it to work. My problem is that my program is
> using a lot of CPU after I ^C the cat /dev/zero and the program is
> doing nothing but sleeping (blocking) on the select(2). I've also
> placed a ticker above the select(2) to visually ensure that the program
> isn't in an infinite loop.
>
> Again, just to clarify: I understand the the program should use a lot
> of CPU while it is read(2)ing from my stress test with cat /dev/zero,
> but _after_ I have ^C the cat, so that the program is doing nothing at
> all and awaiting more things to read(2), it continually shows high CPU
> usage with ps aux - but the CPU grandually goes back down to normal.
CPU usage is always averaged over a period of time. You'll no doubt find a
similar gradual increase if you start your program first, wait a while (with
it blocked in open()), then execute the cat command above.
Alex
|
|
|
|
|