주기적으로 함수를 호출하려면 어떻게 해야 하나요?
글쓴이: yserzero / 작성시간: 금, 2009/09/04 - 7:00오후
안녕하세요.
제가 프로그래밍 경험이 적어서 잘 모르는 게 많습니다.
리눅스에서 C++로 프로그래밍을 하고 있습니다.
주기적으로 예를 들어, 1분마다 함수를 호출을 하고 싶은데 어떻게 해야 하나요?
찾아보니 time.h에 있는 timer_create()를 사용하면 된다는데 어떻게 해야 하는지 잘 모르겠습니다.
아니면 timer_settime()를 이용하는지요?
인자로 줘야하는 값들에 대해서도 잘 이해가 안 갑니다.
아주 간단한 예제라도 있으면 좋을텐데 찾을 수가 없어서 질문을 올리게 되었습니다.
아시는 분 계시면 답변 부탁드립니다.
따라할 수 있는 예제도 있으면 더 바랄게 없습니다.
Forums:
간단한 rt timer 예제
RT timer는 Realtime 라이브러리와 사용되므로 -lrt 넣고 링킹해주셔야 합니다.
초기 타이머 만료는 2.5초, 그 뒤로는 4.0초의 인터벌 타이머 만료시간을 갖습니다.
확인은 타이머 만료마다 시간을 출력하도록 해놨으니 쉽게 확인 가능할 것입니다.
(C파일이 업로드가 안되니 확장자를 제거하고 올립니다. 붙여서 쓰세요)
========================================
* 부분이 전체를 대변하는 하나의 속성일때 진리이다.
영속적이지 못한 것은 전체가 될 수 없다.
========================================
* The truth will set you free.
rt timer 예제 감사합니다.
친절한 예제와 답변에 감사드립니다.
제가 하고 싶은 것은 클래스의 멤버함수를 주기적으로 호출하는 것입니다.
제가 sunyzero님이 제공해주신 자료를 이용하여 다음과 같이 간략하게 구현하였고, 컴파일 후 문제 없이 돌아갑니다.
h_rt_timer() 안에서 클래스의 멤버함수에 접근하기 위해서 static 클래스 포인터 변수를 선언한 후 접근하였습니다.
이것이 괜찮은 방법인 것인지, 아니면 더 좋은 방법을 아시는 분은 답변 부탁드립니다.
------------------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#define SIGNO_RTTIMER SIGRTMIN
#define GET_TIME0(a) get_time0(a, sizeof(a)) == NULL ? "error" : a
inline char * get_time0(char *buf, size_t sz_buf);
int inst_timer(void);
void h_rt_timer(int signum, siginfo_t *si, void *sv);
class Ti {
public:
int Start() {
sigset_t sigset_timer;
if (inst_timer() == -1) {
return EXIT_FAILURE;
}
sigemptyset(&sigset_timer);
while (1) {
sigsuspend(&sigset_timer);
}
}
int Check() {
std::cout
//if (check == 특정값) {
// return -1
//}
return 0;
}
};
static Ti* s_ti;
int main(int argc, char *argv[])
{
Ti ti;
ti.Start();
return 0;
}
int inst_timer(void)
{
struct sigaction sa_rt1;
struct sigevent sigev;
timer_t rt_timer;
struct itimerspec rt_itspec;
char ts_now[20];
memset(&sa_rt1, 0, sizeof(sa_rt1));
sigemptyset(&sa_rt1.sa_mask);
sa_rt1.sa_sigaction = h_rt_timer; /* rt_timer handler */
sa_rt1.sa_flags = SA_SIGINFO;
if (sigaction(SIGNO_RTTIMER, &sa_rt1, NULL) == -1) {
perror("FAIL: sigaction()");
return -1;
}
sigev.sigev_notify = SIGEV_SIGNAL; /* RT signal notification */
sigev.sigev_signo = SIGNO_RTTIMER;
/* create timer */
if (timer_create(CLOCK_REALTIME, &sigev, &rt_timer) == -1) {
perror("FAIL: timer_create()");
return -1;
}
rt_itspec.it_value.tv_sec = 2;
rt_itspec.it_value.tv_nsec = 500000000;
rt_itspec.it_interval.tv_sec = 4;
rt_itspec.it_interval.tv_nsec = 0;
printf("Enable timer at %s.\n", GET_TIME0(ts_now));
if (timer_settime(rt_timer, 0, &rt_itspec, NULL) == -1) {
perror("FAIL: timer_settime()");
return -1;
}
return 0;
}
inline char * get_time0(char *buf, size_t sz_buf)
{
#define STR_TIME_FORMAT "%H:%M:%S"
struct timespec tspec;
struct tm tm_now;
if (buf == NULL) return NULL;
if (clock_gettime(CLOCK_REALTIME, &tspec) == -1) {
return buf;
}
localtime_r((time_t *)&tspec.tv_sec, &tm_now);
if (strftime(buf, sz_buf, STR_TIME_FORMAT, &tm_now) == 0) {
return buf;
}
return buf;
}
void h_rt_timer(int signum, siginfo_t *si, void *sv)
{
char ts_now[20];
printf("-> RT timer expiration at %s\n", GET_TIME0(ts_now));
int check = s_ti->Check();
if (check == -1) {
// 종료
}
}
----------------------------------------------------------------------------
그리고 이 timer를 종료시키는 방법도 아시는 분 있으시면 답변 부탁드립니다.
제가 원하는 것은 Check() 에서 특정 값이 리턴되면 timer가 종료되는 것입니다.
time.h의 timer_delete()를 사용하면 될 것 같은데 이 함수를 어디서 어떤 식으로 사용하고, timerid는 어떻게 얻어와야 하는지를 잘 모르겠습니다.
timer_t rt_timer를 전역으로 선언하고 h_rt_timer() 안에서 timer_delete() 호출을 하면 종료가 되지 않더군요.
제가 하고도 너무 이상한 방법이 아닐까 생각합니다.
ps. 적어놓은 소스 부분이 글쓰기 완료하면 다 적혀지지가 않아서 파일 첨부합니다.
alarm 함수를
alarm 함수를 이용하시는 게 가장 간단할 겁니다.
SIGARLM에 대해 signal handler function를 등록해놓고 alarm을 reset하면
일정 주기마다 호출되어 그 함수가 실행되는 거죠.
SIGARLM는 무엇인가요?
답변 감사합니다.
그런데 SIGARLM는 무엇이고 어디에 정의되어 있나요?
검색 엔진에서
검색 엔진에서 유닉스 시그널 SIGALRM 등으로 검색하시면 더 많은 정보를 얻을 수 있어요~
댓글 달기