/* real_timer.c
A demonstration of the use of (real-time) timers created using setitimer().
Usage: real_timer [secs [usecs [int-secs [int-usecs]]]]
Defaults: 2 0 0 0
The command-line arguments are the second and microsecond settings for
the timer's initial value and interval.
The version of this code shown in the first print of the book contained
an error in the main() function whereby 'maxSigs' was initialized before
'itv', even though the initialization of the former variable depends on the
initialization of the latter variable. See the erratum for page 983 to 984.
*/
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#include "tlpi_hdr.h"
static volatile sig_atomic_t gotAlarm = 0;
/* Set nonzero on receipt of SIGALRM */
/* Retrieve and display the real time, and (if 'includeTimer' is
TRUE) the current value and interval for the ITIMER_REAL timer */
static void
displayTimes(const char *msg, Boolean includeTimer)
{
struct itimerval itv;
static struct timeval start;
struct timeval curr;
static int callNum = 0; /* Number of calls to this function */
if (callNum == 0) /* Initialize elapsed time meter */
if (gettimeofday(&start, NULL) == -1)
errExit("gettimeofday");
if (callNum % 20 == 0) /* Print header every 20 lines */
printf(" Elapsed Value Interval\n");
if (gettimeofday(&curr, NULL) == -1)
errExit("gettimeofday");
printf("%-7s %6.2f", msg, curr.tv_sec - start.tv_sec +
(curr.tv_usec - start.tv_usec) / 1000000.0);
if (includeTimer) {
if (getitimer(ITIMER_REAL, &itv) == -1)
errExit("getitimer");
printf(" %6.2f %6.2f",
itv.it_value.tv_sec + itv.it_value.tv_usec / 1000000.0,
itv.it_interval.tv_sec + itv.it_interval.tv_usec / 1000000.0);
}
printf("\n");
callNum++;
}
static void
sigalrmHandler(int sig)
{
gotAlarm = 1;
}
int
main(int argc, char *argv[])
{
struct itimerval itv;
clock_t prevClock;
int maxSigs; /* Number of signals to catch before exiting */
int sigCnt; /* Number of signals so far caught */
struct sigaction sa;
if (argc > 1 && strcmp(argv[1], "--help") == 0)
usageErr("%s [secs [usecs [int-secs [int-usecs]]]]\n", argv[0]);
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = sigalrmHandler;
if (sigaction(SIGALRM, &sa, NULL) == -1)
errExit("sigaction");
/* Set timer from the command-line arguments */
itv.it_value.tv_sec = (argc > 1) ? getLong(argv[1], 0, "secs") : 2;
itv.it_value.tv_usec = (argc > 2) ? getLong(argv[2], 0, "usecs") : 0;
itv.it_interval.tv_sec = (argc > 3) ? getLong(argv[3], 0, "int-secs") : 0;
itv.it_interval.tv_usec = (argc > 4) ? getLong(argv[4], 0, "int-usecs") : 0;
/* Exit after 3 signals, or on first signal if interval is 0 */
maxSigs = (itv.it_interval.tv_sec == 0 &&
itv.it_interval.tv_usec == 0) ? 1 : 3;
displayTimes("START:", FALSE);
if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
errExit("setitimer");
prevClock = clock();
sigCnt = 0;
for (;;) {
/* Inner loop consumes at least 0.5 seconds CPU time */
while (((clock() - prevClock) * 10 / CLOCKS_PER_SEC) < 5) {
if (gotAlarm) { /* Did we get a signal? */
gotAlarm = 0;
displayTimes("ALARM:", TRUE);
sigCnt++;
if (sigCnt >= maxSigs) {
printf("That's all folks\n");
exit(EXIT_SUCCESS);
}
}
}
prevClock = clock();
displayTimes("Main: ", TRUE);
}
}
- 타이머를 사용한 프로그램의 경우 디버깅이 잘 동작하지 않았다
/* ptmr_sigev_signal.c
This program demonstrates the use of signals as the notification mechanism
for expirations of a POSIX timer. Each of the program's command-line
arguments specifies the initial value and interval for a POSIX timer. The
format of these arguments is defined by the function itimerspecFromStr().
The program establishes a handler for the timer notification signal, creates
and arms one timer for each command-line argument, and then pauses. Each
timer expiration causes the generation of a signal, and, when invoked, the
signal handler displays information about the timer expiration.
Kernel support for Linux timers is provided since Linux 2.6. On older
systems, an incomplete user-space implementation of POSIX timers
was provided in glibc.
*/
#define _POSIX_C_SOURCE 199309
#include <signal.h>
#include <time.h>
#include "curr_time.h" /* Declares currTime() */
#include "itimerspec_from_str.h" /* Declares itimerspecFromStr() */
#include "tlpi_hdr.h"
#define TIMER_SIG SIGRTMAX /* Our timer notification signal */
static void
handler(int sig, siginfo_t *si, void *uc)
{
timer_t *tidptr;
tidptr = si->si_value.sival_ptr;
/* UNSAFE: This handler uses non-async-signal-safe functions
(printf(); see Section 21.1.2) */
printf("[%s] Got signal %d\n", currTime("%T"), sig);
printf(" *sival_ptr = %ld\n", (long) *tidptr);
printf(" timer_getoverrun() = %d\n", timer_getoverrun(*tidptr));
}
int
main(int argc, char *argv[])
{
struct itimerspec ts;
struct sigaction sa;
struct sigevent sev;
timer_t *tidlist;
int j;
if (argc < 2)
usageErr("%s secs[/nsecs][:int-secs[/int-nsecs]]...\n", argv[0]);
tidlist = calloc(argc - 1, sizeof(timer_t));
if (tidlist == NULL)
errExit("malloc");
/* Establish handler for notification signal */
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
if (sigaction(TIMER_SIG, &sa, NULL) == -1)
errExit("sigaction");
/* Create and start one timer for each command-line argument */
sev.sigev_notify = SIGEV_SIGNAL; /* Notify via signal */
sev.sigev_signo = TIMER_SIG; /* Notify using this signal */
for (j = 0; j < argc - 1; j++) {
itimerspecFromStr(argv[j + 1], &ts);
sev.sigev_value.sival_ptr = &tidlist[j];
/* Allows handler to get ID of this timer */
if (timer_create(CLOCK_REALTIME, &sev, &tidlist[j]) == -1)
errExit("timer_create");
printf("Timer ID: %ld (%s)\n", (long) tidlist[j], argv[j + 1]);
if (timer_settime(tidlist[j], 0, &ts, NULL) == -1)
errExit("timer_settime");
}
for (;;) /* Wait for incoming timer signals */
pause();
}
이것도 디버깅이 잘 동작되지 않는다 ..
- setitimer 이용
V8.1(add itimer to system_server fix)
https://github.com/w10sim/FIleServer_Linux_SystemProgramming