转载自:http://blog.csdn.net/a1009563517/article/details/47079883
与无名管道不同,FIFO可用于无关系的进程之间
1.管道读写端操作,如果读写端有一方读或写没打开,则另一端阻塞直到打开(非阻塞情况下会成功打开)
2.如果管道buf满了没有剩余空间,则写端会阻塞直到管道有pipe_buf的空间(如果管道是以非阻塞打开的,则空间满了继续写那么出错返回)
3.读段会一直阻塞直到写端向读端写入数据(非阻塞情况下出错返回)
4.多个读段去读,如果读的buf小于PIPE_BUF则读取操作时原子操作,如果buf>PIPE_BUF则读取操作是非原子的,读取出来的数据是混乱的直至最后一个访问管道的进程结束,内存里的管道数据会被删除,但是管道还在
int main()
{ FILE * b_fd; int b_ret, b_num = 0; char * b_fifo_name = "/tmp/fifo"; pid_t b_pid[10]; unlink(b_fifo_name); b_ret = mkfifo(b_fifo_name, 0777); if(b_ret < 0) { printf("mkfifo fail line = %d, fun = %s, file = %s", __LINE__, __func__, __FILE__); return -1; } b_pid[b_num] = fork(); if(b_pid[b_num] < 0) { return -1; } if(0 == b_pid[b_num]) { /*子线程*/ ipc_pipe_fun1(); } b_num++; b_pid[b_num] = fork(); if(b_pid[b_num] < 0) { return -1; } if(0 == b_pid[b_num]) { /*子线程*/ ipc_pipe_fun1(); } b_num++; b_pid[b_num] = fork(); if(b_pid[b_num] < 0) { return -1; } if(0 == b_pid[b_num]) { /*子线程*/ ipc_pipe_fun2(); } b_num++; while(1) { sleep(10000); } return 0;
} int ipc_pipe_fun1()
{ int b_ret = 0, b_ttl = 0; char b_buf[4098]; int b_fd = open("/tmp/fifo", O_RDONLY|O_NONBLOCK); while(1) { memset(b_buf, 0, sizeof(b_buf)); b_ret = read(b_fd, b_buf, 100); printf("b_ret = %d, b_buf = %s\n", b_ret, b_buf); } return 0;
} int ipc_pipe_fun2()
{ int b_ret; char b_buf[100]; int b_num = 0, b_len = 0, b_ttl = 0; char * b_mall = (char *)malloc(65535); int b_fd = open("/tmp/fifo", O_WRONLY|O_NONBLOCK); while(1) { memset(b_buf, 0, sizeof(b_buf)); sprintf(b_buf, "%d|", b_num); b_num = (++b_num)%1000000; printf("==================\n"); b_len = write(b_fd, b_buf, 100); b_ttl += b_len; printf("b_ttl = %d, b_len = %d, b_buf = %s\n", b_ttl, b_len, b_buf); } return 0;
}