星期日, 六月 03, 2007

Apache运行时库中的进程锁 -- apr_proc_mutex 命名所的扩展

Apache运行时库中的进程锁 得到一个明确的事实,那就是apr实现的进程锁其实时无名锁,只能在fork出的父子进程中互锁。


然而,通过直接进行系统调用实现命名锁的有2个比较显著的问题,1,代码移植性不够好,posix或sysv,fcntl或flock等实现在不同的系统上接口会有所不同。2,代码封装与风格问题,到现在,越来越不惜欢没有经过分装的直接操作了!

所以,将apr_proc_mutex做了几个扩展操作函数,为apr提供了命名的进程锁。

APR_LOCK_PROC_PTHREAD机制的锁没有实现完毕,会出现SIGBUS错误,其他的模式在fedora core 6上测试都是没问题的啦!
扩展的procx_mutex可以去我的网站下载了,必须需要apr库,仅仅添加了一个头文件。

#include "apr_pools.h"
#include "apr_general.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_file_io.h"

#include "apr.h"
#include "apr_shm.h"
#include "apr_file_io.h"
#include "apr_proc_mutex.h"
#include "apr_errno.h"
#include "apr_general.h"
#include "apr_getopt.h"
#include "errno.h"
#include "assert.h"
#include "stdlib.h"


#define MAX_ITER 200
#define CHILDREN 6
#define MAX_COUNTER (MAX_ITER * CHILDREN)

void errlog(apr_status_t s, const char*log)
{
char errbuff[PATH_MAX];

if(log)
printf(log);
if(s!=APR_SUCCESS)
{
printf(apr_strerror(s,errbuff ,PATH_MAX));
abort();
}
}

int main(int argc, char* argv[])
{
apr_pool_t *pool;
apr_status_t rv;
const char* lockname = "/tmp/lock";
apr_lockmech_e mech = APR_LOCK_DEFAULT;
/*
APR_LOCK_FCNTL, fcntl()
APR_LOCK_FLOCK, flock()
APR_LOCK_SYSVSEM, System V Semaphores
APR_LOCK_PROC_PTHREAD, POSIX pthread process-based locking //Test failed
APR_LOCK_POSIXSEM, POSIX semaphore process-based locking
APR_LOCK_DEFAULT Use the default process lock
*/

if (mech==APR_LOCK_POSIXSEM)
lockname = "/posixlock";

static apr_proc_mutex_t *proc_lock;

apr_initialize();
apr_proc_mutex_unix_setup_lock_ex();

rv = apr_pool_create(&pool, NULL);
errlog(rv,"apr_pool_create\n");


#if USE_FORK
if(fork()!=0) {
#endif
if(argc==2 && strcmp(argv[1],"init")==0)
{
rv = apr_proc_mutex_create_ex(&proc_lock, lockname, mech, pool);
errlog(rv,"apr_proc_mutex_create_ex\n");

printf("Init OK\ndefulat=%s\nmutex=%s\nlocalfile=%s\n",apr_proc_mutex_defname(),apr_proc_mutex_name(proc_lock),apr_proc_mutex_ex_lockfile(proc_lock));

do{
errlog(0, "P Enter to lock\n");
getchar();
rv = apr_proc_mutex_lock(proc_lock);
errlog(rv, "P apr_proc_mutex_lock\n");
printf("P Enter to unlock\n");
getchar();

rv = apr_proc_mutex_unlock(proc_lock);
errlog(rv, "P apr_proc_mutex_unlock\n");
}while(1);
exit(0);
}
#if USE_FORK
}else {
#endif
printf("Child Mode\n");
// if (apr_proc_mutex_create_ex(&proc_lock, lockname, mech, pool))
rv=apr_proc_mutex_child_init_ex(&proc_lock, lockname, mech, pool);
errlog(rv,"C failed apr_proc_mutex_child_init\n");

printf("Init OK\ndefulat=%s\nmutex=%s\nlocalfile=%s\n",apr_proc_mutex_defname(),apr_proc_mutex_name(proc_lock),apr_proc_mutex_ex_lockfile(proc_lock));

do{
printf("C Enter to lock\n");
getchar();
rv = apr_proc_mutex_lock(proc_lock);
errlog(rv, "C apr_proc_mutex_lock\n");
printf("C Enter to unlock\n");
getchar();
rv = apr_proc_mutex_unlock(proc_lock);
errlog(rv, "apr_proc_mutex_unlock\n");
}while(1);

#if USE_FORK
}
#endif

exit(0);
return 0;
}

没有评论: