pipe,管道,在Linux里是一种基本的IPC(Inter Process Communication,进程间通讯),rtt中使用pipe这个函数需要打开RT_USING_POSIX,既然是POSIX,那么跟Linux中的pipe应该没有多大区别,可以直接参考linux的pipe。但是在linux中,管道是用在父子进程之间的,而rtt的线程并没有血缘关系,所以rtt中应该是没有什么限制的。还需要打开RT_USING_DFS_DEVFS这个宏,用来支持虚拟文件的,pipe需要用到。DevFS 即设备文件系统,在 RT-Thread 操作系统中开启该功能后,可以将系统中的设备在 /dev 文件夹下虚拟成文件,使得设备可以按照文件的操作方式使用 read、write 等接口进行操作。
pipe函数
int pipe(int fildes[2]); //这里的fildes应该是file descriptor的缩写。
参数fildes是一个2个整形大小的数组,实际上是两个伪文件描述符,pipe成功创建返回0, 失败返回-1。
fildes[0]表示读端,fildes[1]表示写端,它们是只读和只写的,所以它们是单向通讯的。pipe是用ringbuffer和waitqueue实现的,ringbuffer用来缓存数据,waitqueue用来实现阻塞。ringbuffer的大小默认为512byte(PIPE_BUFSZ 512)。
pipe demo
这里就不分析pipe的实现源码了,直接上实例了。
pipe_test.c
#include
#include "dfs_posix.h"
int fs[2];
int pipe_test(void)
{
char buf[10];
int i, j, len;
//int pipe(int fildes[2])
pipe(fs);
for (j = 0; j < 3; ++j) {
rt_kprintf("read(%d) : ", j);
len = read(fs[0], buf, 10);
for (i = 0; i < len; ++i)
rt_kprintf(" %d", buf);
rt_kprintf("
");
rt_kprintf("pipe(%d) test finish!
", j);
}
return 0;
}
void pipe_write(void)
{
char buf[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int res;
res = write(fs[1], buf, sizeof(buf)>>1);
rt_kprintf("write res : %d
", res);
}
FINSH_FUNCTION_EXPORT(pipe_write, pipe_write)
MSH_CMD_EXPORT(pipe_write, pipe_write)
void pipe_close(void)
{
close(fs[0]);
close(fs[1]);
}
FINSH_FUNCTION_EXPORT(pipe_close, pipe_close)
MSH_CMD_EXPORT(pipe_close, pipe_close)
pipe的使用非常简单,注意在调用pipe时,已经open过了,所以不需要再次open,但是需要我们手动close。
如果管道中没有数据,read会发生阻塞。这里的read跟write其实就跟普通的文件读写没什么区别。
测试结果也符合我们的预期。
原作者:上发条
|