About pthread ( timeout function )

2023. 4. 2. 22:56IT

반응형

pthread를 사용해 timeout function 을 만들어 보았다.
근데 이게 main과 동작 function을 분리하니 timer가 제대로 돌아가지 않는것이다.

ㅠㅠ 이해를 못하니 뭘 더 어떻게 빼야 동작하는지를 몰랐는데 ,
수정본을 받아보니 이해가 된다.

먼저 소스 구성은 다음과 같다.
1. main 함수에서 init과 destroy만 해주고,
2. 실행 함수 (다른 c file) 안에서 mutex_lock & timedwait & mutex_unlock을 해준다.(timeout실행)

그래서 ...

난 처음에 이렇게 2개만 main 함수 밖에서 선언해줬는데,
pthread_mutex_t event_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t event_queue_cond;

근데.. 사실상
pthread_condattr_t condattr; 얘까지 빼줘야한다. 왜냐하면,
아래와 같이 main 함수에서 init과 destroy를 해주고, 나머지를 todo function (timeout 동작할 function) 에 넣어주ㅓ야함..

(고로 아래와 같이 짜야한다는 말임..)

pthread_mutex_t t_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  t_cond;
pthread_condattr_t t_condattr;

main() {
	result = pthread_condattr_init(&tcondattr);
	if(result < 0) {
    	printf("init condattr fail:%d \n", result);
    	deinit();
    	return result;
	}
	pthread_condattr_setclock(&t_condattr, CLOCK_MONOTONIC);
	pthread_cond_init(&t_cond, &t_condattr);
	pthread_mutex_init(&t_mutex, 0);
	
	// TODO function() <-- 여기서 timedwait()
    
    pthread_mutex_destroy(&t_mutex);
	pthread_cond_destroy(&t_cond);
	pthread_condattr_destroy(&t_condattr);
}

그리고 그 TODO function안에서 아래와 같이 timedwait을 해준다.

uint8_t TODO() {
	struct timespec timeout;

	clock_gettime(CLOCK_MONOTONIC, &timeout);
	timeout.tv_sec = timeout.tv_sec + NETWORK_WAITING_TIME;
	timeout.tv_nsec = 0;

	pthread_mutex_lock(&t_mutex);
    
	... something_todo_between mutex lock/unlock!
    
	ret = pthread_cond_timedwait(&t_cond, &t_mutex, &timeout); // timeout
	pthread_mutex_unlock(&t_mutex);
	if (ret == ETIMEDOUT)
    	printf("Timeout to wait for network ready\n");
	else if (ret)
    	printf("Error for network wait:%d\n", errno);
	return 1;
}

보면
1. pthread_condattr_init으로 t_condattr 초기화 하고,
2. mipcd_condattr에 setclock으로 CLOCK_MONOTONIC 으로 시간 set해주고, (default값은 원래 CLOCK_REALTIME or CLOCKMONOTONIC 이라고 함)
3. cond_init에서 cond_t 를 t_condattr로 초기화 하는용도로 사용해준다.
4. mutex_init 는 0(NULL)로 초기화.

그리고
5. TODO function 안에서 mutex_lock먼저 해주고,
6. cond_timedwait 으로 설정한 시간만큼 wait 한다.

pthread_cond_wait() 과 pthread_cond_timedwait()은 취소 상태 함수이다.
timedwait()의 경우 다음과 같은 에러코드를 리턴한다.
ETIMEDOUT -> 시간초과 검사를 위해 지정된 시간을 초과해서 signal 이 발생하지 않았을때.
EINTR -> 시그널 등에 의해서 인터럽트가 발생 했을 때.
EBUSY -> cond에 기다리고 있는 Thread가 남아있을때.

7. 그리고 mutex_unlock으로 해제.

8. 마지막으로 할당했던 mutex, cond, condattr를 다 destroy 해준다.

setclock으로 condaddr를 CLOCK_MONOTONIC(부팅이후 시간.특정시간부터 흐른 시간을 측정) 으로 초기화 해주고, 그 값을 cond_init 으로 조건 변수를 또 초기화 해 준거니까, 애초에 condaddr이 기본 값(?)인거니까...

근데 이걸 안으로 넣어놨으니 인식 할리가 없지.( 난 이렇게 이해함... )

💢Reference

 
728x90
반응형