POSIX 세마포어를 사용하여 C에서 스레드 안전 읽기/쓰기 잠금을 쓰려고합니다. 소스 코드 here의 현재 상태를 볼 수 있습니다. 독자가 선호하는 자물쇠를 만들기 위해 this을 추적했습니다.C에서 읽기 - 쓰기 잠금 스레드 안전 파괴 파괴
문제는 내가 rwl_destroy()가 호출 될 때있을 수있는 가능한 상태에 대한 잠금의 파괴를 처리하고자하는 것입니다. 만약 파괴
호출하고 다른 스레드가 다음 잠금 지키고 데이터에 액세스하는 다른 스레드를 방지하기 위해 (작가에 의해 사용됨) WRT를 잠급니다 잠금에 없습니다. 다음에는 destroy 함수가 세마포어를 없애고 ReadWriteLock 구조체에 할당 된 메모리를 해제해야합니다. 하지만 다른 스레드가 현재 잠금을 기다리고 있다면 어떻게 될까요? 문서에 따르면이 스레드는 정의되지 않은 상태로 남습니다.
그건 내가 잠금 장치를 사용하기 쉽게하기 위해 피하려고하는 것입니다.
편집 :
이현재 코드는 다음과 같습니다
typedef struct ReadWriteLock
{
sem_t wrt;
sem_t mtx;
sem_t delFlag;
int readcount;
int active;
}ReadWriteLock;
//forward declaration
/* This function is used to take the state of the lock.
* Return values:
* [*] 1 is returned when the lock is alive.
* [*] 0 is returned when the lock is marked for delete.
* [*] -1 is returned if an error was encountered.
*/
int isActive(ReadWriteLock*);
int rwl_init(ReadWriteLock* lock)
{
lock = malloc(sizeof(ReadWriteLock));
if (lock == NULL)
{
perror("rwl_init - could not allocate memory for lock\n");
return -1;
}
if (sem_init(&(lock->wrt), 0, 1) == -1)
{
perror("rwl_init - could not allocate wrt semaphore\n");
free(lock);
lock = NULL;
return -1;
}
if (sem_init(&(lock->mtx), 0, 1) == -1)
{
perror("rwl_init - could not allocate mtx semaphore\n");
sem_destroy(&(lock->wrt));
free(lock);
lock = NULL;
return -1;
}
if (sem_init(&(lock->delFlag), 0 , 1) == -1)
{
perror("rwl_init - could not allocate delFlag semaphore\n");
sem_destroy(&(lock->wrt));
sem_destroy(&(lock->mtx));
free(lock);
lock = NULL;
return -1;
}
lock->readcount = 0;
lock->active = 1;
return 0;
}
int rwl_destroy(ReadWriteLock* lock)
{
errno = 0;
if (sem_trywait(&(lock->wrt)) == -1)
perror("rwl_destroy - trywait on wrt failed.");
if (errno == EAGAIN)
perror("rwl_destroy - wrt is locked, undefined behaviour.");
errno = 0;
if (sem_trywait(&(lock->mtx)) == -1)
perror("rwl_destroy - trywait on mtx failed.");
if (errno == EAGAIN)
perror("rwl_destroy - mtx is locked, undefined behaviour.");
if (sem_destroy(&(lock->wrt)) == -1)
perror("rwl_destroy - destroy wrt failed");
if (sem_destroy(&(lock->mtx)) == -1)
perror("rwl_destroy - destroy mtx failed");
if (sem_destroy(&(lock->delFlag)) == -1)
perror("rwl_destroy - destroy delFlag failed");
free(lock);
lock = NULL;
return 0;
}
int isActive(ReadWriteLock* lock)
{
errno = 0;
if (sem_trywait(&(lock->delFlag)) == -1)
{
perror("isActive - trywait on delFlag failed.");
return -1;
}
if (errno == EAGAIN)
{//delFlag is down, lock is marked for delete
perror("isActive - tried to lock but ReadWriteLock was marked for delete");
return 0;
}
return 1;
}
나는 또한 이러한 기능이 있습니다
이int rwl_writeLock(ReadWriteLock*);
int rwl_writeUnlock(ReadWriteLock*);
int rwl_readLock(ReadWriteLock*);
int rwl_readUnlock(ReadWriteLock*);
그래서 제 질문은 당신이 정의를 피하기 위해이 기능을 변경하는 방법입니다 상태 I. ReadWriteLock을 파괴하기 전에이 코드의 사용자가 모든 잠금을 해제 할 책임이 있습니까?
이 isActive() 함수와 delFlag 세마포어
그들은 문제를 해결하기 위해 내 시도에서 만들어진, 현재 사용되지 않습니다. 당신은 당신의하는 ReadWriteLock 인스턴스의 "배치"상태를 구현해야
질문에 문제가있는 코드를 포함하십시오. 링크가 끊어지면 문제는 문맥없이 여기에 있습니다. – xxbbcc
이것은 평생 관리 문제입니다. 프로그램이 파괴 된 후 객체를 사용하면 일반적으로 버그라고합니다. –
@xxbbcc 코드를 게시 할 수는 있지만 도움이 될 것이라고 생각하지 않습니다. 문제는 이론적입니다. 내 질문을 업데이트 할게. – JasonPap