My requirement is
There is a reader process the gets data from multiple writers. The writers
will send data to the reader only occassionally. So when they send, reader
has to capture and work on that data.
So, i went for nonblocking FIFO. After opening the fifo, i use fscanf to
read the length arguement, followed by fread of "length" bytes within an
infinite while loop,. After reading, and processing, again fscanf will be
called, and when no data in FIFO, it returns a value <=0 and this continues.
The client code, on a particular scenario, opens fifo for writing, writes to
the fifo and closes.
So with this requirement,
I want to use select so that fscanf() does not get called infinitely and
return with <=0 (which may consume cpu). If select is not appropriate, can
you suggest what else i can do for this scenario?
Please find attached the code server code and the client code:
SERVER:
pipe1_fd = open(FIFO_NAME, open_mode);
printf("File descriptor = %d\n",pipe1_fd);
pipe_fd= fdopen(pipe1_fd,"r");
if (pipe_fd != NULL)
{
printf("After open\n");
while(1)
{
if(1 == isready(pipe1_fd))
{
read_res =
fscanf(pipe_fd,"%d%c",&length,&c);
if (read_res <= 0)
{
memset(arr,'\0',4096);
length=0;
}
else
{
read_res = fread((void
*)arr,sizeof(char),length,pipe_fd);
if (read_res ==length)
{
printf("bytes read
=%d\n",read_res);
printf("Result = %s\n",
arr);
}
else
perror("read error");
}
read_res = read(pipe1_fd,arr,length+4);
printf("READ RESULT = %d\n",read_res);
memset(arr,'\0',4096);
}
}
}
fclose(pipe_fd);
unlink(FIFO_NAME);
CLIENT:
length=strlen("1000,CR,[04/16/08 13:28:45] [9238] [cobmaknk]
[cobm_iProcessParseErrorPayment], M.14: ,Installing converter failed,START
processing Payment, 0 pending\n");
strcpy(arr,"1000,CR,[04/16/08 13:28:45] [9238] [cobmaknk]
[cobm_iProcessParseErrorPayment], M.14: ,Installing converter failed,START
processing Payment, 0 pending\n");
write_res = fprintf(server_fifo,"%d,%s",length,arr);
printf("Written %d bytes : Count = %d\n",write_res,i);
fclose (server_fifo);
On 4/30/08, Thomas Hruska <[EMAIL PROTECTED]> wrote:
>
> Sathya Raghunathan wrote:
> > I opened a named pipe fd in read/nonblocking mode, and then associated a
> > stream using fdopen
> >
> > int pipe1_fd = open("/tmp/myfirstfifo", open_mode);
> > FILE *pipe_fd= fdopen(pipe1_fd,"r");
> >
> > First time, the read gets blocked on select with a time out of 20 secs
> as
> > set in the function call(expected behaviour).
> > Once there is something in the pipe, select returns and FD_ISSET
> succeeds.
> >
> > But after the first successful read from pipe, the while loop continues
> and
> > the next select always returns 1 instead of blocking again for 20
> secs(Note:
> > I am not writing any data to the pipe at this time). I am not able to
> reset
> > the fds' value. How can i do that? What went wrong? Is it because i am
> > mixing file descriptor and the stream?
> >
> > The code is
> >
> > main()
> > {
> > fd_set fds;
> > while(1)
> > {
> > if(isready(pipe_fd1,&fds)==1)
> > // there is data to process...
> > // read using fscanf(%d%c",&length,&comma) and
> fread(pipe_fd,buffer,length);
> > else
> > // there is no data to process. need to block on select
> > }
> > }
> >
> >
> > isready(int fd, fd_set *fds)
> > {
> > FD_ZERO(fds);
> > FD_SET(pipe_fd,fds);
> > rc = select(fd+1, fds, NULL, NULL, NULL);
> > if rc<0
> > return -1
> > FD_ISSET(fd,fds)?1:0;
> > }
>
> Which mode is the pipe opened up in? Blocking or non-blocking? You
> aren't very clear on that.
>
> Your use of select() is likely wrong. select() only CHECKS for
> readability/writability/etc. There is NO GUARANTEE that the pipe is
> actually readable between the select() call and the time the pipe is
> attempted to be read. If the pipe is blocking, you can end up blocking
> during the attempted read. If the pipe is non-blocking, there might not
> be any data there during the read. Both scenarios can (and do) result
> in obscure errors.
>
> Don't worry - it took almost 7 years before someone pointed out that
> mistake to me. Using select() properly is actually much less intuitive
> than the documentation makes it out to be. Basically - if you are using
> it to poll some state of a socket/pipe/resource thinking a future call
> will succeed based on the output of select(), you are using the function
> incorrectly and the application design is flawed. Using it incorrectly
> also creates very ugly code while using it correctly creates much more
> elegant code.
>
> --
> Thomas Hruska
> CubicleSoft President
> Ph: 517-803-4197
>
> *NEW* MyTaskFocus 1.1
> Get on task. Stay on task.
>
> http://www.CubicleSoft.com/MyTaskFocus/<http://www.cubiclesoft.com/MyTaskFocus/>
>
>
>
[Non-text portions of this message have been removed]