2023. 4. 2. 22:56ㆍIT
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
- https://nxmnpg.lemoda.net/3/pthread_condattr_setclock
- https://hand-over.tistory.com/74 ( CLOCK gettime )
- https://docs.oracle.com/cd/E19455-01/806-5257/6je9h032q/index.html ( Condition Variable Attributes )
- https://www.joinc.co.kr/w/man/3/pthread_cond_wait (cond wait에 대한 설명)
'IT' 카테고리의 다른 글
Kernel Timer (0) | 2023.08.19 |
---|---|
현업에서 쓰는 Git, Gerrit ( svn 에서 처음 git 을 사용하는 유저.. ) (1) | 2023.04.10 |
pyyaml version upgrade 시 Command ! (2) | 2022.07.26 |
Ubuntu update 시 에러 날 경우! (0) | 2022.07.26 |
Installation issue: "Failed building wheel for pycairo" (1) | 2022.07.21 |