[Linux] Time/Clock , Signal, WDT

정재훈·2022년 4월 11일
0

Linux

목록 보기
15/19

리눅스 시스템 날짜 & 시간

협정 세계 시 UTC : 국제 표준 시간, 한국(KST) = UTC + 9시간

H/W 시간 : RTC(Real Time Clock) -> hwclock 명령어로 확인
OS 시간 : date명령어로 확인
서버 시간 : 타임 서버의 시간 정보를 확인 : rdate 명령어로 확인

참고) RTC : 전원 공급 없이도 수은 건전지가 부착되어 있어서 소량의 전원으로도 동작하는 시계

날짜 & 시간 명령어들

date : OS시간 읽기
sudo hwclock : RTC H/W시간 정보 값 읽기
sudo hwclock -s : RTC 시간을 시스템 시간에 맞추기
sudo hwclcok -w : 시스템 시간을 RTC 시간에 맞추기
sudo apt install rdatesudo rdate time.bora.net : 보라넷 타임서버의 시간을 가져와 맞추기

time_t

time_t time(NULL) : 1970년 1월 1일 0시 0초부터 현재 시간까지 지난 , time_t의 자료형은 64비트 unsigned 정수형 숫자이다.

#include <stdio.h>
#include <time.h>

int main()
{
    time_t t = time(0); // 
    struct tm *tmm = localtime(&t); // localtime : 사람이 보기 편한 정보로 확인 가능
    char vect[10][10] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
    printf("%d month\n" , tmm->tm_mon); // 현재 달 - 1
    printf("%d hour\n" , tmm->tm_hour);
    printf("%d min\n" , tmm->tm_min);
    printf("%d sec\n" , tmm->tm_sec);
    printf("%s \n" , vect[tmm->tm_wday]);

    return 0;
}

10억번 연산에 걸리는 시간 time( )으로 구하기

#include <stdio.h>
#include <time.h>

int main()
{
    time_t start = time(0); // 시작 시간

    int sum = 4;
    for (int i = 1; i<=1000000000;i ++) {
        sum = sum % i; // 모듈러 연산 10억번 실행
    }
    time_t end = time(0); // 끝 시간
    printf("%ld sec\n", end - start); // 끝 시간과 시작 시간을 빼서 작동한 초 확인하기

    return 0;
}

Clock( )

프로세스 Clock이다. 현재 프로세스가 시작되고, 얼마나 시간이 흘렀는지의 시간

시스템 clock 확인 방법

#include <stdio.h>
#include <time.h>

int main()
{
    printf("%ld\n", CLOCKS_PER_SEC); // 1000000 : 백만, 따라서, 1클럭은 1us이다.
    return 0;
}

10억번 연산에 걸리는 시간 clock( )으로 구하기

#include <stdio.h>
#include <time.h>

int main()
{
    clock_t start = clock();

    int sum = 4;
    for (int i = 1; i<=1000000000;i ++) {
        sum = sum % i;
    }
    clock_t end = clock();
    printf("%ld clock\n", end - start); // 3751361 clock

    return 0;
}

나의 컴퓨터의 CLOCKS_PER_SEC는 1,000,000으로 1/10^-6 이므로 1us을 뜻합니다. 따라서, 10억변 연산을 time( )에서 구한 4초와 clock( )에서 구한 3.751361 s는 비슷하다는 결론이다.

gettimeofday( )

time함수와 비슷하게, 1970년부터 현재 시간 값을 얻지마, us단위로 더 정밀하게 얻을 수 있다.

Signal

시그널 : 특정 이벤트가 발생했을 때 신호를 보내서 알려준다.
kill -l : 시그널 종류를 확인하는 명령어

인터럽트 : CPU가 동작 중, 하던 일을 멈추고 처리하도록 하는 것
SW Interrupt 발생시 콜백함수 처럼 예약된 함수가 동작합니다.

중요) ISR(Interrupt Service Routine) = 인터럽트 핸들러
인터럽트에 대응하여 호출되는 함수로 해당 ISR을 처리하면 원래 하던 동작으로 돌아간다.

Signal API

signal(시그널번호, 헨들러이름) : 핸들러 함수 등록
API => kill -[시그널번호] [PID] or killall -[시그널번호] [process 이름]

sig.c

#include <stdio.h>
#include <signal.h> // singnal LIB
#include <unistd.h>

void gogo(int sig_no)
{
    printf("%d\n", sig_no);
    printf("GOGO\n");
}

int main()
{
    signal(SIGUSR1, gogo); // 핸들러 함수 등록

    while(1) sleep(1);

    return 0;
}

다른 터미널에서 killall -SIGUSR1 sig을 통해 핸들러 실행한다.

Alarm API

특정 시간 후 SIGALRM Signal을 발생한다. alarm을 다시 울리면 갱신된다.

WDT

Watchdog Timer : 임베디드 시스템에서 오작동을 막기 위한 타이머로 무한루프를 돌거나 응답이 없을 때 timeout이 되어 리셋 등이 된다.
디버깅할 때 자주 사용되고, 안정장치로 활용된다.

wdt.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void gogo()
{
    printf("SYSTEM ERROR\n");
    exit(1);
}

int main(int argc, char *argv[])
{
    signal(SIGALRM, gogo);
    alarm(3); // 3초후 갱신 안될시 gogo 함수 실행

    char buf[100];
    while(1) {
        printf("INPUT >> "); 
        scanf("%s", buf);
        printf("%s\n", buf);
        alarm(3); // 입력하면 갱신
    }

    return 0;
}

profile
여러 방향으로 접근하는 개발자

0개의 댓글