원샷 타이머의 경우 세마포어를 사용하여 타이머 콜백 완료를 기다릴 수 있습니다. 그러나 타이머가 여러 번 실행되면 도움이되지 않습니다. 단지 타이머를 무장 해제 (이 경우 무장했다)와 타이머 자원 assocoated을 해제한다모든 스레드 타이머 콜백 완료를 기다리는 안전한 방법
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define N 10
void timer_threaded_function(sigval_t si)
{
uint8_t *shared_resource = si.sival_ptr;
sleep(rand() % 7);
/* ... manipulate with shared_resource */
return;
}
int main()
{
struct sigevent sig_ev = {0};
uint8_t *shared_resource = malloc(123);
timer_t timer_id;
int i;
sig_ev.sigev_notify = SIGEV_THREAD;
sig_ev.sigev_value.sival_ptr = shared_resource;
sig_ev.sigev_notify_function = timer_threaded_function;
sig_ev.sigev_notify_attributes = NULL;
timer_create(CLOCK_REALTIME, &sig_ev, &timer_id);
for (i = 0; i < N; i++) {
/* arm timer for 1 nanosecond */
timer_settime(timer_id, 0,
&(struct itimerspec){{0,0},{0,1}}, NULL);
/* sleep a little bit, so timer will be fired */
usleep(1);
}
/* only disarms timer, but timer callbacks still can be running */
timer_delete(timer_id);
/*
* TODO: safe wait for all callbacks to end, so shared resource
* can be freed without races.
*/
...
free(shared_resource);
return 0;
}
timer_delete() : 다음 코드를 고려하십시오. 그러나 타이머 콜백은 여전히 실행 중일 수 있습니다. 그래서 우리는 shared_resource를 해제 할 수 없습니다. 그렇지 않으면 경쟁 조건이 발생할 수 있습니다. 이 상황에 대처할 수있는 방법이 있습니까?
레퍼런스 카운팅에 대해서는 언급하고 있지만 실제로 쓰레드가 실제로 공유 리소스에 액세스하려고 시도하는 양 (타이머 오버런의 원인)을 알지 못하기 때문에 도움이되지 않습니다.
일부 분리 된 스레드가 공유 자원을 조작하는 것을 어떻게 확인하겠습니까? 문제를 해결하고이 문제를 해결했습니다. 'timer_' API는 약간의 붉은 청어입니다. '분리 된 쓰레드는 타이머, 시그널, 루프가'pthread_create()'를 호출함으로써 생성된다는 사실을 염두에 두어야합니다. – pilcrow