write_lock이 하나라도 있으면 read_lock에 참여하지 못하도록 하는 것 아닌가요? 어떻게 구현하셨기에..
한 녀석이 read lock(shared lock이란 소리죠?)을 얻은 상태에서 다른 녀석들이 read_lock 과 write_lock을 요구할 경우, read_lock이 계속 우선권을 얻고 들어가게 구현하셨다는 소리 같은데요. 실제로 이렇게 할 경우, write lock은 위에서 질문하신 것 처럼 starvation에 빠지게 되겠죠.
해결책은 지금 생각 나는 것은.. write_lock 을 요구한 넘에게 카운터 하나 달아서 카운터가 꽉 차면 read_lock을 요구하는 넘이 있어도 못 얻도록 한다던가.. 머 그럼 되지 않을까요? 그냥 지금 생각한 건데..;; 헐헐;;
write_lock이 하나라도 있으면 read_lock에 참여하지 못하도록 하는 것 아닌가요? 어떻게 구현하셨기에..
한 녀석이 read lock(shared lock이란 소리죠?)을 얻은 상태에서 다른 녀석들이 read_lock 과 write_lock을 요구할 경우, read_lock이 계속 우선권을 얻고 들어가게 구현하셨다는 소리 같은데요. 실제로 이렇게 할 경우, write lock은 위에서 질문하신 것 처럼 starvation에 빠지게 되겠죠.
해결책은 지금 생각 나는 것은.. write_lock 을 요구한 넘에게 카운터 하나 달아서 카운터가 꽉 차면 read_lock을 요구하는 넘이 있어도 못 얻도록 한다던가.. 머 그럼 되지 않을까요? 그냥 지금 생각한 건데..;; 헐헐;;
결국 write 가 굶어 죽기전에 read 를 굶기는 방식이군요..ㅎㅎ
아마도 질문자는 하나의공유메모리로 다중프로세스간통신을 하는모양입니다.
프로세스들이 항상 리스닝하고 있다면 비효율적이므로 새메지지가 있을때만 즉각적으로 읽어들이도록 구현하시면 되는데 구현이 조금 복잡해는면도 있습니다.
라면이라도 끓여주면되지 않나요?ㅡ,.ㅡ;read를 대신굶기면 될듯
라면이라도 끓여주면되지 않나요?ㅡ,.ㅡ;
read를 대신굶기면 될듯합니다...
----------------------------------------------------------------------------
write_lock이 하나라도 있으면 read_lock에 참여하지 못하도
write_lock이 하나라도 있으면 read_lock에 참여하지 못하도록 하는 것 아닌가요? 어떻게 구현하셨기에..
[quote="cdpark"]write_lock이 하나라도 있으면 rea
한 녀석이 read lock(shared lock이란 소리죠?)을 얻은 상태에서 다른 녀석들이 read_lock 과 write_lock을 요구할 경우, read_lock이 계속 우선권을 얻고 들어가게 구현하셨다는 소리 같은데요. 실제로 이렇게 할 경우, write lock은 위에서 질문하신 것 처럼 starvation에 빠지게 되겠죠.
해결책은 지금 생각 나는 것은.. write_lock 을 요구한 넘에게 카운터 하나 달아서 카운터가 꽉 차면 read_lock을 요구하는 넘이 있어도 못 얻도록 한다던가.. 머 그럼 되지 않을까요? 그냥 지금 생각한 건데..;; 헐헐;;
http://home.postech.ac.kr/~sodomau
[quote="sodomau"][quote="cdpark"]write_l
결국 write 가 굶어 죽기전에 read 를 굶기는 방식이군요..ㅎㅎ
아마도 질문자는 하나의공유메모리로 다중프로세스간통신을 하는모양입니다.
프로세스들이 항상 리스닝하고 있다면 비효율적이므로 새메지지가 있을때만 즉각적으로 읽어들이도록 구현하시면 되는데 구현이 조금 복잡해는면도 있습니다.
----------------------------------------------------------------------------
답변들 감사합니다.근데 약간은 추상적이라 구현에 문제가 있네요..
답변들 감사합니다.
근데 약간은 추상적이라 구현에 문제가 있네요..
통신을 하는것은 아니구요
통신용 세마포어는 작성이 되어 동작을 잘하고 있습니다.
공유메모리 풀을 만들어 사용을 하고 있습니다.
근데 이넘이 자료구조가 좀 복잡하게 되어 있어서.
일단 구현을 보시구 좀더 구체적인 변경방법을..^^;
/******************************************************* * System V 세마포어를 이용한 READ LOCK/WRITE LOCK * 현재 write lock 가 경쟁상태에서 굶는문제 있음--; *******************************************************/ /* read/write락을 사용하는 함수에서의 변수들 초기화 여부 */ static char _is_init_lock_op = 0; static struct sembuf _get_rlock_op [2]; /* read 락 요청 */ static struct sembuf _release_rlock_op [1]; /* read 락 해제 */ static struct sembuf _get_wlock_op [3]; /* write 락 요청 */ static struct sembuf _release_wlock_op [1]; /* write 락 해제 */ /* 데이타 통신용으로 사용하는 세마포어 lock */ static struct sembuf _get_cli_lock_op [3]; /* writer 락요청 */ static struct sembuf _release_cli_lock_op [2]; /* writer 락해제(데이타) */ static struct sembuf _release_cli_lock_op_n[1]; /* writer 락해제(NO데이타)*/ static struct sembuf _get_svr_lock_op [3]; /* reader 락요청 */ static struct sembuf _release_svr_lock_op [1]; /* reader 락해제(처리) */ static struct sembuf _release_svr_lock_op_n[2]; /* reader 락해제(NO처리) */ /* READ / WRITE LOCK에 필요한 sembuf구조를 초기화( 않되어 있다면) */ static void _init_sem_v_lock_op() { if( ! _is_init_lock_op ) { /****************************** * 읽기 쓰기 락 관련 OP셋팅 * 0 Read 락 * 0 Write 락 ******************************/ L_MEMSET(_get_rlock_op, 0, sizeof(_get_rlock_op)); L_MEMSET(_release_rlock_op, 0, sizeof(_release_rlock_op)); L_MEMSET(_get_wlock_op, 0, sizeof(_get_wlock_op)); L_MEMSET(_release_wlock_op, 0, sizeof(_release_wlock_op)); /* 읽기락 요청용 Write 세마포어가 0이 될때까지 대기 0 read 세마포어 1증가 1 */ set_sem_buf( &_get_rlock_op[0], 1, 0, 0); set_sem_buf( &_get_rlock_op[1], 0, 1, SEM_UNDO); /* 읽기락 해제용 read 세마포어 1 감소 */ set_sem_buf( &_release_rlock_op[0], 0, -1, SEM_UNDO | IPC_NOWAIT); /* 쓰기락 요청용 write 세마포어가 0이 될때까지 대기 0 read 세마포어가 0이 될때까지 대기 1 write 세마포어 1 증가 2 */ set_sem_buf( &_get_wlock_op[0], 1, 0, 0); set_sem_buf( &_get_wlock_op[1], 0, 0, 0); set_sem_buf( &_get_wlock_op[2], 1, 1, SEM_UNDO); /* 쓰기락 해제용 write 세마포어 1 감소 */ set_sem_buf( &_release_wlock_op[0], 1, -1, SEM_UNDO | IPC_NOWAIT); /******************************************* * 클라이언트 / 서버형태의 데이타 IPC락형태 * 두개의 세마포어를 사용한다 * 0 자원 유무 세마포어 * 1 프로세싱중 여부 세마포어 *******************************************/ L_MEMSET(_get_cli_lock_op, 0, sizeof(_get_cli_lock_op)); L_MEMSET(_release_cli_lock_op, 0, sizeof(_get_cli_lock_op)); L_MEMSET(_release_cli_lock_op_n, 0, sizeof(_release_cli_lock_op_n)); L_MEMSET(_get_svr_lock_op, 0, sizeof(_get_svr_lock_op)); L_MEMSET(_release_svr_lock_op, 0, sizeof(_release_svr_lock_op)); L_MEMSET(_release_svr_lock_op_n, 0, sizeof(_release_svr_lock_op_n)); /* 클라이언트 데이타 넣기 전 락 요청 자원이 0인지 검사 존재하는지 검사 0 진행중인 프로세스가 0인지 검사 1 진행중인 프로세스를 1로 올림 2 */ set_sem_buf( &_get_cli_lock_op[0], 0, 0, 0); set_sem_buf( &_get_cli_lock_op[1], 1, 0, 0); set_sem_buf( &_get_cli_lock_op[2], 1, 1, SEM_UNDO); /* 클라이언트 데이타가를 넣고 난 이후 락 Release 자원 카운트를 1증가시키고 0 진행중인 프로세스를 -1 감소시킴 1 */ set_sem_buf( &_release_cli_lock_op[0], 0, 1, IPC_NOWAIT); set_sem_buf( &_release_cli_lock_op[1], 1, -1, SEM_UNDO | IPC_NOWAIT); /* 클라이언트 데이타를 넣지 않고 락 Release 진행중인 프로세스를 -1 감소시킴 0 */ set_sem_buf( &_release_cli_lock_op_n[0], 1, -1, SEM_UNDO | IPC_NOWAIT); /* 서버에서 데이타가 존재할때 읽어가기 위한 락 요청 자료가 존재하는지 확인후 -1 감소시킴 0 프로세싱 카운트가 0인지 확인 1 프로세싱 카운트 1 증가 2 */ set_sem_buf( &_get_svr_lock_op[0], 0, -1, 0); set_sem_buf( &_get_svr_lock_op[1], 1, 0, 0); set_sem_buf( &_get_svr_lock_op[2], 1, 1, SEM_UNDO); /* 서버에서 데이타를 처리했을때를 위한 락 release 프로세싱 카운트 -1 감소시킴 0 */ set_sem_buf(&_release_svr_lock_op[0], 1, -1, SEM_UNDO | IPC_NOWAIT); /* 서버에서 데이타를 처리하지 못했을때의 락 release 프로세싱 카운트 -1 감소 0 자료를 처리하지 못했음으로 자원카운트 1증가 1 */ set_sem_buf(&_release_svr_lock_op_n[0], 1, -1, SEM_UNDO | IPC_NOWAIT); set_sem_buf(&_release_svr_lock_op_n[1], 0, 1, IPC_NOWAIT); /* 초기화 되었음을 표시 */ _is_init_lock_op = 1; } /* if */ return; } /* _init_sem_v_lock_op() */ /* 락관리 자료구조를 초기화 */ V_SEM_MANAGER get_lock_sem_v( key_t sem_key) { V_SEM_MANAGER ret_val; L_MEMSET(&ret_val, 0, sizeof(ret_val)); _init_sem_v_lock_op(); /* 세마포어 생성 */ if( get_sem_v(&ret_val, sem_key, 2) < 0 ) { L_DEBUG( (LOG_APPEND, "세마포어 생성실패\n") ); ret_val.is_valid = 0; return ret_val; } /* if */ return ret_val; } /* init_lock_sem_v() */ /* 읽기 락 요청 */ int get_rlock_sem_v( V_SEM_MANAGER * sem_lock) { _init_sem_v_lock_op(); return sem_v_op(sem_lock, _get_rlock_op, L_ARRAY_SIZE(_get_rlock_op)); } /* get_rlock_sem_v() */ /* 읽기 락 해제 요청 */ int release_rlock_sem_v( V_SEM_MANAGER * sem_lock) { _init_sem_v_lock_op(); return sem_v_op(sem_lock, _release_rlock_op, L_ARRAY_SIZE(_release_rlock_op)); } /* release_rlock_sem_v() */ /* 쓰기 락 요청 */ int get_wlock_sem_v( V_SEM_MANAGER * sem_lock) { _init_sem_v_lock_op(); return sem_v_op(sem_lock, _get_wlock_op, L_ARRAY_SIZE(_get_wlock_op)); } /* get_wlock_sem_v() */ /* 쓰기 락 해제 요청 */ int release_wlock_sem_v( V_SEM_MANAGER * sem_lock) { _init_sem_v_lock_op(); return sem_v_op(sem_lock, _release_wlock_op, L_ARRAY_SIZE(_release_wlock_op)); } /* release_wlock_sem_v() */여기서 데이타 통신용으로 사용하는 세마버퍼들은 필요없구요.
나머지 세마버퍼들은 초기화 된 이후 op에 static로 사용될 뿐입니다.
댓글 달기