naobe @ ウィキ
apr(Apatch Portable Runtime)
最終更新:
Bot(ページ名リンク)
-
view
Apacheに戻る
参考URL
http://apr.apache.org/
http://bookend.take-uchi.net/apr/
http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial.html#toc2
http://blog.so-net.ne.jp/user_localhost_sec/2009-01-13
http://bookend.take-uchi.net/apr/
http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial.html#toc2
http://blog.so-net.ne.jp/user_localhost_sec/2009-01-13
概要
OS(Unix,Windows,beos,netware,os2,AIX,os360)に関係なく、Cのruntimeを統一したインタフェースで扱えるようにしたライブラリ。すべてのOSについて完全には使えない。オープンソースなので、不足しているところは使用者にまかせるスタンス。
メモリ、スレッド、文字列、ファイル、ハッシュ、ロックなどのインタフェースがある。
メモリ、スレッド、文字列、ファイル、ハッシュ、ロックなどのインタフェースがある。
メモリ管理
メモリプールを作成してその中から必要なメモリを供給する。メモリが必要になったら、apr_pallocを呼ぶ。apr_pallocを呼ぶとallocatorに保管しているメモリを返す(apr_pool_destroyを使ってpoolを開放するとallocatorにメモリを保管する)。allocatorにメモリがない場合は、4KBでアラインした領域をmallocしてpoolにリンクして返す。apr_pool_destroyを使ってメモリを開放してもデフォルトでは、OSにまったく返却しない。返却したプールは、アロケータに保管して必要になったときに再使用する。
4KB(たぶんページサイズ)区切りで大き目にメモリをmallocするため、フラグメントを軽減する。またallocatorに保管して再利用するためシステムコールを発行する回数が減る。
4KB(たぶんページサイズ)区切りで大き目にメモリをmallocするため、フラグメントを軽減する。またallocatorに保管して再利用するためシステムコールを発行する回数が減る。
以下の関数でアロケータの持つ最大メモリ容量を設定しておくと、allocatorに返却したメモリの合計が最大メモリ容量を超えたら、それ以後はOSにfreeして返す。allocatorからメモリを獲得するとallocatorの空き容量が増えて、その分はOSに返却しないでallocatorに保管する。
void apr_allocator_max_free_set ( apr_allocator_t *allocator, apr_size_t size )
sizeは、要求メモリサイズを4KBで割ったもの
メモリの返却は、pool単位で明示的に行わなければならない。 JavaのGCのように自動的に返却するものではい。
【ソース解読】
ApachePortableRuntime.xls

array
C言語の配列は、あらかじめサイズを決めておいてその範囲内で使う。aprのarrayは、サイズが不足すると内部で自動的にサイズを拡張する。スタックとしても使える。
apr_array_header_t* apr_array_make(apr_pool_t *p, int nelts, int elt_size )
配列を作成する。pはプール、neltsは配列の初期サイズ。初期サイズを超えて要素を追加すると、内部で自動的にサイズを増やす(サイズを倍にする)。elt_sizeは要素のサイズ。
struct apr_array_header_t { /** The pool the array is allocated out of */ apr_pool_t *pool; /** The amount of memory allocated for each element of the array */ int elt_size; /** The number of active elements in the array */ int nelts; /** The number of elements allocated in the array */ int nalloc; /** The elements in the array */ char *elts; };
戻り値のapr_array_header_tは、配列本体。neltsは、登録した要素の数。nallocは配列の容量(要素の数)、要素を格納するために取得したメモリの数(単位は、elt_size)。eltsは配列の先頭ポインタ。直接eltsを操作して要素を取得する。
void* apr_array_push(apr_array_header_t *arr)
配列に要素を格納するために使用する。配列の次の登録位置を返す。
void* apr_array_pop(apr_array_header_t *arr)
配列の末尾要素の位置を返す。また登録要素数をデクリメントする。
要素の削除。更新機能はない。裸で配列をさらしているので、自由に操作してということか。
【サンプルプログラム】
#include <stdlib.h> #include <apr_file_io.h> #include <apr_strings.h> #include <apr_tables.h> // 配列初期サイズ #define INIT_ARRAY_SIZE 3 static apr_file_t *apr_stdout, *apr_stdin, *apr_stderr; int main(int argc, const char * const *argv) { apr_pool_t *p; int i; apr_app_initialize(&argc, &argv, NULL); apr_pool_create(&p, NULL); apr_file_open_stdout(&apr_stdout, p); apr_file_open_stdin(&apr_stdin, p); apr_file_open_stderr(&apr_stderr, p); // array作成 apr_array_header_t *arr = apr_array_make(p, INIT_ARRAY_SIZE, sizeof(char *)); // 要素追加 *(const char **) apr_array_push(arr) = apr_pstrdup(p, "aaa"); *(const char **) apr_array_push(arr) = apr_pstrdup(p, "bbb"); *(const char **) apr_array_push(arr) = apr_pstrdup(p, "ccc"); APR_ARRAY_PUSH(arr, const char *) = apr_pstrdup(p, "ddd"); APR_ARRAY_PUSH(arr, const char *) = apr_pstrdup(p, "eee"); apr_file_printf(apr_stdout, "配列サイズ:%d\n", arr->nelts); // 一覧表示 for (i = 0; i < arr->nelts; i++) { char *ptr = ((char **)arr->elts)[i]; apr_file_printf(apr_stdout, "push element:%s\n", ptr); } apr_file_printf(apr_stdout, "\n"); // pop char **elm; while(elm = apr_array_pop(arr)) { apr_file_printf(apr_stdout, "pop element:%s\n", *elm); } apr_file_printf(apr_stdout, "配列サイズ:%d\n", arr->nelts); apr_file_printf(apr_stdout, "\n"); apr_pool_destroy(p); apr_terminate(); return EXIT_SUCCESS; }
コマンドオプション
以下の関数を使って、コマンドオプションを取得する
APR_DECLARE(apr_status_t) apr_getopt_init(apr_getopt_t **os, apr_pool_t *cont, int argc, const char *const *argv) APR_DECLARE(apr_status_t) apr_getopt(apr_getopt_t *os, const char *opts, char *optch, const char **optarg)
apr_getopt_initを使ってメモリプールからapr_getopt_tを作成する。apr_getopt_tには引数が格納されている。apr_getoptを順次使うと、指定したオプションの値をoptch, optargに格納する。例えば、command -a aaaと指定するとoptchは、'a'でoptargは、'aaa'になる。
【サンプルプログラム】
#include <stdlib.h> #include <apr_file_io.h> #include <apr_strings.h> #include <apr_getopt.h> static apr_file_t *apr_stdout, *apr_stdin, *apr_stderr; int main(int argc, const char * const *argv) { apr_pool_t *p; apr_getopt_t *os; char ch; const char *arg; apr_app_initialize(&argc, &argv, NULL); apr_pool_create(&p, NULL); apr_file_open_stdout(&apr_stdout, p); apr_file_open_stdin(&apr_stdin, p); apr_file_open_stderr(&apr_stderr, p); // getopt初期化 apr_getopt_init(&os, p, argc, argv); while(apr_getopt(os,"a:b:cd",&ch, &arg) == APR_SUCCESS) { switch (ch) { case 'a': case 'b': apr_file_printf(apr_stdout, "option char: %c, option arg: %s\n", ch, arg); break; default: apr_file_printf(apr_stdout, "option char: %c\n", ch); break; } } apr_pool_destroy(p); apr_terminate(); return EXIT_SUCCESS; }