先来看下Makefile:
NONBLOCK_WRITER = nb.w
BLOCK_WRITER = b.w
NONBLOCK_READER = nb.r
BLOCK_READER = b.r
all: writer reader
writer:
cc w.c -o $(NONBLOCK_WRITER) -DNONBLOCK
cc w.c -o $(BLOCK_WRITER)
reader:
cc r.c -o $(NONBLOCK_READER) -DNONBLOCK
cc r.c -o $(BLOCK_READER)
clean:
rm -f $(NONBLOCK_WRITER) $(BLOCK_WRITER) $(NONBLOCK_READER) $(BLOCK_READER)
分别将读者进程和写者进程编译成阻塞版本和非阻塞版本。
将公共部分写到一个头文件里:
/* file name: fifotest.h
* cmd: make
* author: yilonglucky#gmail.com
* description: fifo header file
*/
#include
#include
#include
#include
#include
#include
#include
#include
#define FIFO_PATH "/tmp/w.fifo"
#define BUF_LEN (4096*2)
再来看下读者进程的代码:
/* file name: r.c
* cmd: make
* author: yilonglucky#gmail.com
* description: fifo reader
*/
#include "fifotest.h"
int main(int argc, char *argv[])
{
char buf[BUF_LEN];
int fd;
int r_size;
int real_rnum;
if(2 != argc)
{
printf("Usage: %s read_len\n", argv[0]);
exit(0);
}
r_size = atoi(argv[1]);
printf("requred real read %d bytes\n", r_size);
#ifdef NONBLOCK
fd = open(FIFO_PATH, O_RDONLY|O_NONBLOCK, 0);
#else
fd = open(FIFO_PATH, O_RDONLY, 0);
#endif
if(-1 == fd)
{
perror(FIFO_PATH);
exit(2);
}
do
{
memset(buf, 0, sizeof(buf));
real_rnum = read(fd, buf, r_size);
if(-1 == real_rnum)
{
if(EAGAIN == errno)
{
perror("no data so try later");
}
}
else
{
printf("real read %d bytes\n", real_rnum);
}
sleep(1);
}while(1); /* read once while 0 */
close(fd);
unlink(FIFO_PATH);
return 0;
}
/* file name: w.c
* cmd: make
* author: yilonglucky#gmail.com
* description: fifo writer
*/
#include "fifotest.h"
int main(int argc, char *argv[])
{
char buf[BUF_LEN];
int fd;
int w_size;
int real_wnum;
printf("PIPE_BUF = %d\n", PIPE_BUF);
if(2 != argc)
{
printf("Usage: %s write_len\n", argv[0]);
exit(0);
}
w_size = atoi(argv[1]);
printf("requred real write %d bytes\n", w_size);
#if 1 /* you can test ENOENT if 0*/
if((mkfifo(FIFO_PATH, O_CREAT|O_EXCL) < 0) && (EEXIST != errno))
{
printf("%s no exist and create failed\n", FIFO_PATH);
}
#endif
#ifdef NONBLOCK
fd = open(FIFO_PATH, O_WRONLY|O_NONBLOCK, 0);
#else
fd = open(FIFO_PATH, O_WRONLY, 0);
#endif
if(-1 == fd)
{
if(ENXIO == errno)
{
perror("no reading process");
exit(6);
}
else /* ENOENT no access to the fifo */
{
perror(FIFO_PATH);
exit(2);
}
}
sleep(10); /* sleep for nonblock reader's EAGAIN */
memset(buf, 0xf, sizeof(buf));
real_wnum = write(fd, buf, w_size);
if(-1 == real_wnum)
{
if(EAGAIN == errno)
{
/* who can tell me how to be here */
printf("write to fifo error: try later\n");
}
}
else
{
printf("real write num is %d\n", real_wnum);
}
close(fd);
return 0;
}