pipe
pipe: 匿名管道。pipe 是一种 IPC 机制,他的作用是用作有血缘进程间完成数据传递,只能从一端写入,从另外一端读出。为了解决 pipe 的弊端,linux 又引入了 mkfifo(实名管道)。
创建管道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| rt_pipe_t *rt_pipe_create(constchar *name, intbufsz)
{
rt_mutex_init(&pipe->lock, name, RT_IPC_FLAG_FIFO);
rt_wqueue_init(&pipe->reader_queue);
rt_wqueue_init(&pipe->writer_queue);
rt_condvar_init(&pipe->waitfor_parter, "piwfp");
pipe->writer = 0;
pipe->reader = 0;
pipe->bufsz = bufsz;
dev = &pipe->parent;
dev->type = RT_Device_Class_Pipe;
dev->init = RT_NULL;
dev->open = rt_pipe_open;
dev->read = rt_pipe_read;
dev->write = rt_pipe_write;
dev->close = rt_pipe_close;
dev->control = rt_pipe_control;
dev->rx_indicate = RT_NULL;
dev->tx_complete = RT_NULL;
rt_device_register(&pipe->parent, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
return pipe;
}
|
删除管道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| intrt_pipe_delete(constchar *name)
{
device = rt_device_find(name);
if (device)
{
if (device->type == RT_Device_Class_Pipe)
{
rt_pipe_t *pipe;
pipe = (rt_pipe_t *)device;
rt_condvar_detach(&pipe->waitfor_parter);
rt_mutex_detach(&pipe->lock);
rt_device_unregister(device);
if (pipe->fifo)
{
rt_ringbuffer_destroy(pipe->fifo);
pipe->fifo = RT_NULL;
}
rt_free(pipe);
}
}
return result;
}
|
打开管道
1 2 3 4 5 6 7
| rt_mutex_take(&pipe->lock, RT_WAITING_FOREVER);
pipe->fifo = rt_ringbuffer_create(pipe->bufsz);
rt_mutex_release(&pipe->lock);
|
关闭管道
1 2 3 4 5 6 7
| rt_mutex_take(&pipe->lock, RT_WAITING_FOREVER);
rt_ringbuffer_destroy(pipe->fifo);
rt_mutex_release(&pipe->lock);
|
读取管道数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| rt_mutex_take(&pipe->lock, RT_WAITING_FOREVER);
while (read_bytes < count)
{
int len = rt_ringbuffer_get(pipe->fifo, &pbuf[read_bytes], count - read_bytes);
if (len <= 0)
{
break;
}
read_bytes += len;
}
rt_mutex_release(&pipe->lock);
|
写入管道数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| rt_mutex_take(&pipe->lock, RT_WAITING_FOREVER);
while (write_bytes < count)
{
int len = rt_ringbuffer_put(pipe->fifo, &pbuf[write_bytes], count - write_bytes);
if (len <= 0)
{
break;
}
write_bytes += len;
}
rt_mutex_release(&pipe->lock);
|
匿名管道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| intpipe(intfildes[2])
{
rt_pipe_t *pipe;
chardname[8];
chardev_name[32];
staticint pipeno = 0;
rt_snprintf(dname, sizeof(dname), "pipe%d", pipeno++);
pipe = rt_pipe_create(dname, PIPE_BUFSZ);
if (pipe == RT_NULL)
{
return -1;
}
pipe->is_named = RT_FALSE;
rt_snprintf(dev_name, sizeof(dev_name), "/dev/%s", dname);
fildes[0] = open(dev_name, O_RDONLY, 0);
if (fildes[0] < 0)
{
return -1;
}
fildes[1] = open(dev_name, O_WRONLY, 0);
if (fildes[1] < 0)
{
close(fildes[0]);
return -1;
}
return0;
}
|
实名管道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| intmkfifo(constchar *path, mode_tmode)
{
rt_pipe_t *pipe;
pipe = rt_pipe_create(path, PIPE_BUFSZ);
if (pipe == RT_NULL)
{
return -1;
}
return0;
}
|