众所周知,TLS是指线程局部存储,FIFO是Unix中的命名管道,可用于无关进程间的通信,而本文描述的TLS FIFO是指这样一种机制:如果一个线程在每次IO操作时,若没有连接,则先连接到FIFO服务端,再将连接关联到这个线程的TLS中,这里的连接即创建并打开唯一的FIFO,之后的读写就在这个FIFO连接上进行;当FIFO连接断开时,在下次IO操作时会自动重连。这样一来,用户程序就只要调用相关的IO操作,而不必管理连接,极大地简化了程序。使用FIFO通信前先要创建FIFO再打开它,其中创建是最重要的操作,结果有3种情况:成功、失败和已存在。
结构定义
typedef struct
{
int fd;
char *name;
}ipc_fifo_t;
fd存储FIFO文件描述符,name存储FIFO文件系统路径名。
接口函数
● 创建FIFO
ipc_fifo_t* ipc_fifo_make(const char *path,mode_t mode);
path指定FIFO路径,可以是绝对路径或相对路径,mode指定访问权限,若成功则返回一个FIFO结构,否则为NULL;通常被ipc_fifo_open调用。
● 打开FIFO
int ipc_fifo_open(ipc_fifo_t **f,const char *path,int flag,mode_t mode);
flag指定打开标志,如果包含了O_CREAT标志,那么调用ipc_fifo_make创建新的FIFO对象并在打开成功后替换*f,否则如果*f为空,就分配并初始化一个fifo结构;mode指定访问权限,仅当创建时生效。虽然f为输入输出参数,但操作失败时不会影响它,也就是说没有副作用。
● 发送数据
ssize_t ipc_fifo_write(ipc_fifo_t *f,const void *data,size_t size);
如果成功则返回已发送的字节数,否则返回-1,errno表示出错代码。
● 接收数据
ssize_t ipc_fifo_read(ipc_fifo_t *f,void *data,size_t size);
如果成功则返回已发送的字节数,否则返回-1,errno表示出错代码。
● 关闭FIFO
void ipc_fifo_close(ipc_fifo_t *f);
当通信结束的时候,应该调用此函数来关闭FIFO,它会先删除FIFO文件和关闭文件描述符,最后释放fifo结构。
● 获取TLS FIFO
ipc_fifo_t* ipc_fifo_tls_get();
该函数一般被发送数据接口调用,若成功则返回一个FIFO结构,否则为NULL;每个线程对应一个FIFO对象,对于同一线程,获取的是同一个FIFO对象,而后便可调用ipc_fifo_write来发送数据。
工作流程
适用于FIFO客户端和服务端,但服务端由于要异步处理众多FIFO客户端,因此要注意以下2个问题,这也是使用FIFO技术通信的一些细节。
1)必须以非阻塞读写方式打开知名FIFO,即以O_CREAT|O_RDWR|O_NONBLOCK标志来调用ipc_fifo_open,这样才不会阻塞等待某个客户端以同步写方式打开知名FIFO而返回,因为它使用O_RDWR标志,这样自己既读又写,加上O_NONBLOCK,就立即返回了。
2)必须以非阻塞只读方式打开对应客户端FIFO,即以O_RDONLY|O_NONBLOCK标志调用ipc_fifo_open,这样就不会阻塞接受客户端建立连接而返回。
建立FIFO连接
适用于FIFO客户端,被发送数据接口调用,考虑到服务端可能事先没有打开知名FIFO来监听连接,所以这里先以
异步方式写打开知名FIFO,如果成功则改以
阻塞方式发送唯一路径名到服务端,如果发送完全后,接着以
同步方式写打开唯一FIFO,这是为了等待服务端打开了对应的唯一FIFO。
发送数据
适用于FIFO客户端,当TLS中没有关联对应的FIFO时,则先调用fifo_tls_get进入建立FIFO连接流程,而后再发数据。
posted on 2014-12-01 00:13
春秋十二月 阅读(1319)
评论(2) 编辑 收藏 引用 所属分类:
System