SewiGの日記
2006-07-03 [月] [長年日記]
■ [Programming] 集合書き込みと拡散読み出し(1)
これは、1回のシステムコールで2つ以上のバッファに対する出力ができる優れものです。これを集合書き込み(gather write)と言います。<sys/uio.h>で定義されています。
ssize_t writev(int fildes, const struct iovec *iov, int iovcnt);
fildesはファイルディスクリプタです。fopen()より抽象度の低い操作でよく使う識別子です。で、次のiovecがポイントになります。iovecはバッファとその長さを持つ構造体で、その配列を引数に渡します。
caddr_t iov_base; int iov_len;
iovcntは、iovecの要素数。
集合書き込みを利用する場面としては、ネットワークプログラミングが挙げられます。strcatなんかでバッファをメモリ上でバリバリ結合してたらコストが大きいですが、これならデータが用意できた時点で書き込みが行え、これが不可分に行われるのが特長です。なので、UDPデータグラムの生成なんかでは、ヘッダがたくさん付加されますがこれをiovecでまとめておいて、1回のwritev呼び出しで1つのUDPデータグラムが生成できます。
#include <sys/types.h> #include <sys/uio.h> #include <unistd.h> #include <string.h> int main() { int fd; char *buf0 = "妹「"; char *buf1 = "お兄ちゃん大好き♪"; char *buf2 = "」"; int iovcnt; struct iovec iov[3]; fd = creat("hoge.txt", 0644); iov[0].iov_base = buf0; iov[0].iov_len = strlen(buf0); iov[1].iov_base = buf1; iov[1].iov_len = strlen(buf1); iov[2].iov_base = buf2; iov[2].iov_len = strlen(buf2); iovcnt = sizeof(iov) / sizeof(struct iovec); writev(fd, iov, iovcnt); close(fd); return 0; }