주기적으로 함수를 호출하려면 어떻게 해야 하나요?

yserzero의 이미지

안녕하세요.
제가 프로그래밍 경험이 적어서 잘 모르는 게 많습니다.

리눅스에서 C++로 프로그래밍을 하고 있습니다.
주기적으로 예를 들어, 1분마다 함수를 호출을 하고 싶은데 어떻게 해야 하나요?
찾아보니 time.h에 있는 timer_create()를 사용하면 된다는데 어떻게 해야 하는지 잘 모르겠습니다.
아니면 timer_settime()를 이용하는지요?
인자로 줘야하는 값들에 대해서도 잘 이해가 안 갑니다.
아주 간단한 예제라도 있으면 좋을텐데 찾을 수가 없어서 질문을 올리게 되었습니다.
아시는 분 계시면 답변 부탁드립니다.
따라할 수 있는 예제도 있으면 더 바랄게 없습니다.

sunyzero의 이미지

RT timer는 Realtime 라이브러리와 사용되므로 -lrt 넣고 링킹해주셔야 합니다.

초기 타이머 만료는 2.5초, 그 뒤로는 4.0초의 인터벌 타이머 만료시간을 갖습니다.
확인은 타이머 만료마다 시간을 출력하도록 해놨으니 쉽게 확인 가능할 것입니다.

(C파일이 업로드가 안되니 확장자를 제거하고 올립니다. 붙여서 쓰세요)
========================================
* 부분이 전체를 대변하는 하나의 속성일때 진리이다.
영속적이지 못한 것은 전체가 될 수 없다.

댓글 첨부 파일: 
첨부파일 크기
Plain text icon rt_timer.txt2.11 KB

========================================
* The truth will set you free.

yserzero의 이미지

친절한 예제와 답변에 감사드립니다.

제가 하고 싶은 것은 클래스의 멤버함수를 주기적으로 호출하는 것입니다.
제가 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. 적어놓은 소스 부분이 글쓰기 완료하면 다 적혀지지가 않아서 파일 첨부합니다.

댓글 첨부 파일: 
첨부파일 크기
Plain text icon rt_timer2.txt2.4 KB
terzeron의 이미지

alarm 함수를 이용하시는 게 가장 간단할 겁니다.
SIGARLM에 대해 signal handler function를 등록해놓고 alarm을 reset하면
일정 주기마다 호출되어 그 함수가 실행되는 거죠.

yserzero의 이미지

답변 감사합니다.
그런데 SIGARLM는 무엇이고 어디에 정의되어 있나요?

sev314의 이미지

검색 엔진에서 유닉스 시그널 SIGALRM 등으로 검색하시면 더 많은 정보를 얻을 수 있어요~

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.