Computer Science/시스템 프로그래밍

[시스템 프로그래밍] Chapter 9

seungwon9201 2024. 6. 8. 14:29

POSIX Times

Epoch : 컴퓨터 시스템의 시간이 시작된 점 (1970년 1월 1일 00시부터 정의)

 

time함수는 epoch시점부터 현재시점까지 몇초가 흘러갔나를 반환해주는 함수, 32-bit의 long타입인경우 오버플로우가 발생할것이다.
diftime함수는 앞의 시간에서 뒤의 시간값을 빼서 반환해주는 함수, 리턴타입이
localtime함수는 특정시간정보만 알고싶을때 사용하여 구조체로 반환한다/ gmtime함수는 동일한 역할을 수행하는데 local이 아니고 utc시간 기준으로 tm 구조체를 반환해준다. ctime함수는 epoch시점부터 지금까지 몇초가 흘렀는지 스트링형태로 반환, asctime은 기능은 동일하지만 인풋파라미터 타입이 tm구조체가 될수있음,
ctime과 actime비교

tm구조체는 gm이나 locailtime함수의 리턴타입으로 현재시간에대한 요소값을 할당해서 반환해 주는 타입이다.

시간단위별로 나눈것
gettimeofday함수도 epoch부터 현재시간까지 반환을 해주는 함수인데 그 시간 정보를 초 단위가 아니고 마이크로세컨드 단위로 반환해준다. 민액 32비트 long타입이면 최도 durationrkqtdms 2^31 -1msec이고 대략 35분이다.

위의 함수는 구식이라 다른함수를 쓴다

clock_get은 역할은 동일하나 나노세컨드까지 반환해줌 clockgetres를통해서 현재시값을 tmspec구조체 값으로 반환을 해준다, 이러한 것을 가지고 현재 시간값을 알아오기위해서 clockgettime함수를 써서 두번째 파라미터인 timespec구조체 타입으로 최대 나노세컨드타입까지 반환이된다. clocksettime함수는 두번째 파라미터로 주어진 값으로 시간값을 설정하겠다는 함수이다. 실시간 시간정보를 나타내는것이 CLOCK_REALTIME
예시
호출한 프로세스를 지정한시간만큼 중지시키고 리턴시키는 함, nanosleep을 사용하면 나노세컨드만큼 중지시킬수있음


Timer : 우리가 알고있는 타이머와 동일(계속 값이 감소하는 것)

Clock : 계속값이 증가하는것 

REAL은 실제시간으로 작동시킬때 사용, VIRTUAL은 가상시간으로 작동한다,PROF는 VIRTUAL과 비슷함. 가상시간과 프로세스가 실행중일땐 감소한다. settimer를 쓸때 두번째파라미터에 따라 다르게 나온다. NULL이 아니면 이전값 저장되고, 0이아니면 타이머 재시작, 0이면 재시작안하고 초기값이 0이면 작동중인타이머가 중지된다.
POSIX:XSI는 프로세스별로 이미 고정된 타이머 이지만 TMR은 클럭을 이용해서 독립적인 객체를 만들어서 사용할 수 있는 타이머이다. 이전 타이머 보다 TMR타이머가 더 나은 resolutuon을 준다
타어머 객체와 파라미터들
타이머객체를 만들고난 다음 timer_settime으로 시작하거나 중지할 수 있음, timergettime은 현재 남아있는 시간정보를 반환하고 싶을떄 사용한다, overrun은 pending이 되면서 없어진 시그널의 개수를 의미한다. 그래서 getouverrun함수로 잃어버린 시그널의 개수를 반환해서 참조할 수 있으나 자주사용하지는 않음.


Timer drift : 타이머의 완료시점이 딜레이가 생겨서 실제보다 뒤에 타이머가 완료되는 문제

 

생기는 이유 : 타이머가 만료가 됐다가 다시 시작을 하는 지점에서 딜레이가 발생하기 때문이다. 또한 타이머의 세밀도가 10ms라고 가정하자 그럼 타이머는 10, 20, 30 씩 증가한다. 그런데 타이머의 간격을 22라고 설정을 한다면 이 타이머는 22를 표현을 못해서 30에서 만료가 된다. 그래서 내가 원했던 시점보다 8ms가 밀려서 설정이 된다.

 

해결책 : 타이머의 인터벌이 22일때 22 지점에서 다시 시작하지 말고 그다음 타이머가 만료되는 시점에서 지금 타이머의 시간값을 빼자. 기존에 타이머는 22를 표현할 수 없어서 30에서 만료가 되고 그다음 44는 60에서 만료가 되었다. 그래서 다음 타이머의 인터벌 값은 22가 아니고 44에서 30을 뺀 14로 하자. 그럼 44는 실제로 60이 아니고 50에서 만료가 될 것이다. 타이머 drift값은 6이 되지만 누적되어서 늘어나지는 않을 것이다. 그다음 값은 66인데 이전에 만료된 50을 빼면  인터벌값이 16이 된다.

 

POSIX:TMR을 이용하면 timer drift문제를 해결할 수 있다. 왜냐하면 TMR타이머에서는 타이머의 인터벌값을 absolute값으로 설정할 수 있기 때문이다. timersettime의 flags파라미터에 absolute time으로 설정할 수 있어서 사용가능하다.