17 날짜와 시간

이 절은 현재의 시간과, 다르게 시간을 표현하는 방법들 사이의 전환을 결정하는 함수들을 포함하여, 날짜와 시간들을 위한 함수들을 설명하고 있다.

시간 함수들은 세 가지 주요한 범주로 나뉘어진다.

경과된 CPU 시간을 계산하는 함수들은 17. 1절 [Processor Time] 에서 논의되었다.

절대 시각이나 달력 시간을 계산하는 함수들은 17. 2절 [Calendar Time] 에서 논의되었다.

알람과 타이머를 설정하는 함수들은 17. 3절 [Setting an Alarm] 에서 논의되었다.


17. 1 프로세서 타임

만일 당신이 당신의 프로그램을 최적화 하거나, 또는 그 효율성을 계산하려한다면, 어느 주어진 지점이후에, 얼마나 많은 프로세서 시간과 CPU 시간이 흘렀는지를 알 수 있도록 하는 유용한 방법이 있다. 프로세서 시간은 벽시계와는 다른데, 그것은 벽시계가 입/출력이나 다른 어떤 프로세스가 동작하고 있는 동안 얼마나 시간이 흘렀는지를 알리지 않기 때문이다. 프로세서 시간은 데이터 타입 clock_t로 표현되고, 단일한 프로그램의 시작점에서 표시된 어떤 기준 시간과 연관된 시간의 흐름을 숫자로 표현한다.

17. 1. 1 기준 CPU 시간 조사

프로세스에 의해 사용된, 경과된 CPU 시간을 얻기 위해서는, 당신은 clock함수를 사용할 수 있다. 이 함수는 헤더파일 'time. h'에 선언되어 있다.

특별한 사용 예로, 당신이 시작점과 끝점 사이의 시간의 간격을 구하려면, clock함수를 호출하고, 그 값들을 나중 값에서 처음 값을 빼고, 그리고 CLOCKS_PER_SEC로 나누어라( 초당 횟수(clock ticks)의 숫자를 얻기 위해서 ), 다음 프로그램처럼.

#include <time. h>
clock_t start, end;
double elapsed;
start = clock();
. . .
/* 먼저 일을 시작하기 전에 clock함수를 호출한 다음 당신이 경과된 시간을 얻기 원하는 그 일을 시작하라 */
end = clock();
elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;

다른 컴퓨터와 운영체제에서 어떻게 프로세서 시간을 기억하는지는 매우 광범위한 문제이다. 100분의 1초나, 100만분의 1초 사이의 내부프로세스 시계를 갖는 것이 보통이다.

GNU 시스템에서 clock_t는 long int 와 동등하고, CLOCKS_PER_SEC는 정수값이다. 그러나 다른 시스템에서는, clock_t는 정수이고, 매크로 CLOCKS_PER_SEC는 플로팅-포인트 형으로 서로 다르다. 어떤 시스템 하에 놓여있든지 상관없이 적당하게 작업을 수행하고, 산술적으로 그 명령을 확인하기 위해서는 아래의 예처럼 double형으로 프로세스 타임을 cast연산을 통해서 형변환을 하라.

매크로 : int CLOCKS__PER__SEC

이 매크로는 clock 함수에 의해 계산된 초당 시간주기(clock ticks)의 수를 나타내는 값이다.

매크로 : int CLK__TCK

이것은 옛날에 CLOCKS_PER_SEC 대신에 쓰이던 것이다.

데이터타입 : clock__t

이것은 clock함수에 의해 반환된 값의 형으로 시간주기의 단위이다.

함수 : clock_t clock(void)

이 함수는 경과된 프로세서 시간을 반환한다. 기준 시간은 항상 다르지만, 단일 프로세스 안에서는 변경되지 않는다. 만일 그 프로세서 시간이 유용하지 않거나 표현될 수 없다면, clock은 (clock_t)(-1)의 값을 반환한다.

17. 1. 2 자세하게 경과된 CPU 시간에 대한 조사

times 함수는 경과된 프로세서 시간에 대해서 struct tms오브젝트로 더 상세한 정보를 반환한다. 이 함수는 헤더파일 `sys'times. h'에 선언되어 있다.

데이터 타입 : struct tms

tms구조체는 프로세스 시간들에 대한 정보를 반환하는데 사용된다. 그것은 적어도 다음과 같은 멤버들을 포함하고 있다.

clock_t tms_utime

이것은 호출된 프로세스의 명령들을 수행하는데 사용된 CPU 시간이다.

clock_t tms_stime

이것은 호출된 프로세스 때문에 시스템에서 사용된 CPU 시간이다.

clock_t tms_cutime

이것은 wait 또는, waitpid에 의해 부모 프로세스에게 보고된 상황으로, 호출된 프로세스의 모든 종료된 자식 프로세스들의 tms_utime 과 tms_cutime의 값들을 합한 값이다; 23. 6절 [Process Completion] 참조. 즉, 호출한 프로세스의 모든 종료된 자식 프로세스 의 명령을 수행하는데 사용된 총 CPU 시간을 나타낸다.

clock_t tms_cstime

이것은 tms_cutime과 유사하지만, 호출된 프로세스의 모든 종료된 자식 프로세스들을 위하여 시스템에서 사용된 총 CPU 시간을 나타낸다.

모든 시간들은 시간주기(clock ticks)로 주어진다. 이들은 절대값이다; 새로이 만들어진 프로세스에서, 그들은 모두 0이다. 23. 4 [Creatina a Precess] 참조.

함수 : clock_t times (struct tms *buffer)

times 함수는 호출된 프로세스를 위한 프로세서 시간 정보를 buffer에 저장한다. 반환값은 clock()의 값과 동일하다: 어떤 기준 시간에서 실제로 경과된 시간. 기준 시간은 어떤 특별한 프로세스 상에서는 변하지 않는 상수 값이고, 시스템 시작시간과 연관된 시간으로 표현한다. 실패를 하면 (clock_t)(-1)의 값을 반환하다.
이식성 노트: 17. 1. 1절 [Basic CPU Time] 233에서 설명된 clock 함수는, ANSI C 표준함수이고, times 함수는 POSIX. 1의 함수이다. GNU 시스템에서는, clock함수로 표현된 값은 times에 의해 반환된 tms_utime 과 tms_stime의 합계와 동등한 값이다.


17. 2 달력 시간

이 절은 그레고리력에 의한 날짜와 시간들을 기억하기 위한 도구들을 설명하고 있다.

날짜와 시간 정보를 위한 세 가지 표현방법이다.

달력 시간( 데이터 타입 time_t)은 간단히 어떤 정해진 기준시간 이후 몇초가 흘렀는지를 숫자로 표현한다.

또한 초를 미세하게 나누어서 표현하는 고해상도 시간 표현이 있다 (데이터 타입 struct timeval). 당신이 큰 정밀도를 필요로 할 때 보통의 달력 시간대신 이 시간 표현을 사용하라.

지역 시간이나 broken-down time( 데이터타입 struct tm)은 정해진 시간 구역에서 정해진 년, 달, 등등의 구성요소들의 집합으로 날짜와 시간을 표현한다. 이 시간 표현은 보통 형식화된 날짜와 시간 값들을 결합하는데 사용된다.

 

17. 2. 1 간단한 달력 시간

이 절은 달력 시간을 표현하기 위한 데이터 타입 time_t와 달력 시간 오브젝트에서 동작하는 함수들을 설명한다. 이 도구들은 헤더파일 `time. h'에 선언되어 있다.

데이터 타입 : time_t

이것은 달력 시간을 표현하기 위해서 사용하는 데이터 타입이다. GNU C 라이브러리와 다른 POSIX-계열에서, time_t는 long int 와 같다. 절대시간 값으로 해석될 때, 그것은 협정 세계시간 1970년 1월 1일 00: 00: 00 시간 이후 경과된 초의 수를 표현한다. ( 이 날짜는 때때로 시대(epoch)로써 사용된다. ) 다른 시스템에서, time_t는 정수이거나 플로팅-포인트이거나 할 것이다.

함수 : double difftime (time_t time1, time_t time0)

difftime 함수는 double 형으로 time1과 time2 사이의 경과된 시간을 초로 반환한다. GNU 시스템에서, 당신은 간단히 time_t 값들을 빼는 것으로 그 값을 구할 수 있지만, 다른 시스템에서는 time_t 데이터 타입은 직접적으로 빼기를 할 수가 없게, 기호화 되어있을 것이다.

함수 : time_t time (time_t *result)

time 함수는 time_t의 형으로 표현된 값으로 현재의 시간을 반환한다. 만일 인수 result가 널 포인터가 아니라면, time값은 *result에 저장되어진다. 만일 달력 시간이 유용하지 않다면, (time_t)(-1)이 반환된다.

 

17. 2. 2 고해상도 달력

time_t 데이터 타입은 오직 1초 사이의 해상도를 갖는 달력 시간들을 표현하기 위해 사용한다. 어떤 응용프로그램은 더 정밀할 필요가 있다.

그래서, GNU C 라이브러리에서는 1초 보다 더 높은 고해상도의 달력시간을 표현할 용량이 있는 함수들을 갖고 있다. 이 절에서 설명하고 있는 함수들과 연관된 데이터 타입들은 `sys/time. h'에 선언되어 있다.

데이터 타입 : struct timeval

구조체 struct timeval은 달력 시간을 표현한다. 그것은 다음과 같은 멤버들을 갖고 있다.

long int tv_sec

이것은 epoch 이후를 초(second)로 표현한다. 이것은 보통 time_t 값과 동일하다.

long int tv_usec

이것은 마이크로초(microsecond)로 표현된 시간값이다. 어떤 시간 struct timeval 값들은 시간 간격들을 위한 사용자이고, 그러면 tv_sec 멤버는 간격에서 경과된 초(second) 이고, tv_usec는 부가적으로 흐른 시간 마이크로 초의 수이다.

데이터 타입 : struct timezone

구조체 struct timezone는 지역 시간대에 대한 최소의 정보를 저장하기 위해 사용된다. 그것은 다음의 멤버들을 갖는다.

int tz_minuteswest

이것은 그리니치 표준시(GMT)의 minutes west의 수이다.

int tz_dsttime

만일 0이 아니라면, 그 해(year)의 어떤 기간동안 일광 절약시간을 적용한다.

struct timezone 형은 절대값이고 결코 사용할일은 없을 것이다. 대신에 17. 2. 6절 [Time Zone Functions] 에서 설명된 도구들에서 사용한다.

struct timeval형의 두 값들을 빼는 것이 종종 필요하다. 이곳에는 이런 일을 하는 가장 좋은 방법이 있다. 그것은 tv_sec 멤버가 unsigned 형인 어떤 기묘한 운영체제하에서 조차도 돌아간다.

/* `struct timeval'의 형을 가진 값 X 와 Y를 빼고, 그 결과는 RESULT에 저장하라. 그 차이가 음수이면 1을 반환하고, 그렇지 않으면 0을 반환하라 */

int
timeval_subtract (result, x, y)
struct timeval *result, *x, *y;
{
/* 갱신된 y로 나중에 빼기를 하기 위해, y값을 가져와라 */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* 기다림을 위한 시간을 계산하라. tv_usec는 어떤 양의 값이다. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
/* 만일 결과가 음수이면 0을 반환하라 */
return x->tv_sec < y->tv_sec;
}

함수 : int gettimeofday (struct timeval *tp, struct timezone *tzp)

gettimeofday 함수는 tp 가 가리키고 있는 구조체 struct timeval에서 현재의 날짜와 시간을 반환한다. 그 시간대에 대한 정보는 tzp가 가리키고 있는 구조체 안에 반환된다. 만일 tzp 인수가 널 포인터라면, 시간 대 정보는 무시된다. 반환값이 0이면 성공이고, 실패면 -1이다. 다음의 errno는 이 함수를 위해 정의된 에러상황이다.

ENOSYS

운영체제가 시간대 정보 얻는 것을 지원하지 않고, tzp가 널 포인터가 아니다. GNU 운영체제는 시간대 정보를 표현하기 위해서 struct timezone를 사용하는 것을 지원하지 않는다; 그것은 예전에 4. 3 BSD에서 사용되던 것이다. 대신에 17. 2. 6절[Time Zone Functions] 에서 설명된 도구들을 사용하라.

함수 : int settimeofday(const sruct timeval *tp, const struct timezone *tzp)

settimeofday 함수는 인수들에 따라서 현재의 날짜와 시간을 설정한다. gettimeofday를 통해서, 만일 tzp가 널 포인터라면, 시간대 정보는 무시된다. 당신이 settimeofday를 사용할려면 특권이 부여된 사용자이어야만 한다. 성공하면 반환값은 0이고, 실패하면 -1이다.
다음의 errno는 이 함수를 위해 정의된 에러상황이다.

EPERM 이 프로세스가 특권이 없기 때문에 시간을 설정할 수 없다.

ENOSYS 운영체제가 시간대 정보를 설정하는 것을 지원하지 않고 tzp가 널 포인터가 아니다.

함수 : int adjtime (const struct timeval *delta, struct timeval *olddelta)

현재의 시간을 점차적으로 조정하기 위해서 시스템 시계를 빠르게, 또는 느리게 하는 함수이다. 만일 간단히 현재의 시간을 설정할 수 없는, 항상 천편일률적으로 증가하기만 하는 시스템 시계라면, 이것은 그 시간을 맞출 수가 있다.
delta 인수는 현재의 시간을 위한 조정을 지정한다. 만일 음수라면 시스템 시계는 잃어버린 많은 시간을 복구할때까지 천천히 내려가고, 만일 양수라면, 시스템 시계는 천천히 올라간다. 만일 olddelta 인수가 널 포인터가 아니라면, adjtime함수는 조정이 아직 수행되기 전의 앞의 시간에 대한 정보를 반환한다. 이 함수는 특별히 로컬 네트웍상의 컴퓨터들의 시간을 동기화 하는데 사용된다.
당신은 그것을 사용하기 위해서는 특권이 부여된 사용지가 되어야만 한다. 성공하면 0을 반환하고, 실패하면 -1을 반환한다.  
다음의 errno는 이 함수를 위해 정의된 에러상황이다.

EPERM 당신은 시간을 설정할 수 있는 특권을 갖고 있지 않다.

 
이식성 노트 : gettimeofday, settimeofday, 그리고adjtime 함수들은 BSD로부터 왔다.

 

17. 2. 3 Broken-down 시간

달력 시간은 초단위로 표현된다. 이것은 계산하기는 편리하지만, 사람이 보통 날짜와 시간을 표현하는 방법과는 다르다. 그와 달리, broken-down 시간은 연도, 달, 날짜 등을 분리하여 2진으로 표현한다. Broken down 시간값은 계산에는 불편하지만, 그들은 인간이 읽을 수 있는 시간으로 유용하게 사용된다.

broken-down 시간값은 지역시간대의 선택과 항상 연관되어 있고, 그것은 항상 어떤 시간대가 사용되었음을 지적한다. 이 절에 있는 심볼들은 헤더파일 `time. h'에 선언되어 있다.

데이터 타입 : struct tm

이것은 broken-down 시간을 표현하기 위해 사용되는 데이터 타입이다. 그 구조체는 어느 순서로 나타날 수 있는, 적어도 다음과 같은 멤버들을 포함하고 있다.

int tm_sec

이것은 0에서 59까지의 범위를 갖는 초(second)를 표현하고 있다. (실제로는 "윤초"를 허용해서, 61까지가 제한이다. )

int tm_min

이것은 0에서 59까지의 범위를 갖는 분(minute)을 나타낸다.

int tm_hour

이것은 0에서 23까지의 범위를 갖는 시(hours)를 나타낸다.

int tm_mday

이것은 1에서 31까지의 범위를 갖는 달 중의 그날을 나타낸다.

int tm_mon

이것은 0에서 11까지의 범위를 갖는, 1월 이후의 달의 수를 표현한다.

int tm_year

이것은 1900년 이후의 년(year)의 수이다.

int tm_wday

이것은 0에서 6의 범위를 갖는, 일요일을 기점으로 해서 지난날의 수를 나타낸다.

int tm_yday

이것은 0에서 365의 범위를 갖는, 1월 1일 이후 지난날의 수를 나타낸다.

int tm_isdst

이것은 시간을 표현하는데, 일광절약 시간이 영향을 주는지(있었거나, 또는 있을 예정이거나)를 지적하는 플래그이다. 그 값은 만일 일광 절약시간이 영향을 미치면 양수이고, 만일 그렇지 않으면 0이고, 그 정보가 음수이면 유용하지 않다.

long int tm_gmtoff

이 필드는 broken-down 시간값을 계산하는데 사용되어지는 시간대를 나타낸다; 그것은 초의 단위로 그리니치 표준시(GMT)를 얻어서, 그것에 지역시간을 얻기 위해서 더해져야만 하는 양( amount)이다. 그 값은 변화 가능한 시간대( 17. 2. 6절 [Time Zone Functions] 참조. )와 같은 것이다. 당신은 또한 그리니치 표준시의 "seconds west의 수"라고 생각할 수도 있다. tm_gmtoff 필드는 GNU 라이브러리 확장이다.

const char *tm_zone

이것은 broken-down 시간값을 계산하는데 사용되어지는 시간대를 위한 세-문자 이름이다. 이것은 GNU 라이브러리 확장이다.

함수 : struct tm *localtime (const time_t *time)

localtime 함수는 time이 가리키고 있는 달력시간을 사용자가 정한 시간대와 맞추어서, broken-down 시간으로 변환한다. 반환값은 어느 날짜와 시간 함수들을 호출해서 얻은 정적 broken-down 시간 구조체를 가리키고 있는 포인터이다. (그러나 어느 다른 라이브러리 함수도 이 오브젝트의 내용에 덧씌우기 (overwrite)를 할 수 없다. ) localtime을 호출하는 것은 다른 하나의 영향이 있다: 그것은 변수 tzname를 현재 시간대에 대한 정보로 설정한다. 17. 2. 6절 [Time Zone Functions] 참조.

함수 : struct tm *gmtime(const time_t *time)

이 함수는 broen-down이 세계 협정시간으로 표현된다는 것을 제외하고, localtime과 유사하다. _그리니치 표준시가 지역 시간대와 더 연관이 있다. 달력 시간들은 항상 세계 협정시로 표현된다는 것을 기억하라.

함수 : time_t mktime(struct tm *brokentime)

mktime 함수는 broken-down 시간 구조체를 달력시간 표현으로 변환시키기 위해서 사용된다. 그것은 다른 날짜에 기초하여 연도(year), 주(week)의 날수와 시간 요소들을 채워서 broken-down 구조체의 내용을 "일반화"한다.
mktime함수는 broken-down 시간 구조체의 멤버인 tm_wday와 tm_yday의 정해진 내용들을 무시한다. 그것은 달력 시간을 계산하기 위해서 다른 구성요소의 값들을 사용한다; 그것은 그들의 보통 범위의 밖에 있는 비일반화된 값들을 갖는 그들 구성요소들을 위해서 허용되었다. mktime이 마지막으로 하는 일은 brokentime 구조체의 구성요소들을 조정하는 것이다( tm-wday 와 tm-yday를 포함해서 ). 만일 정해진 broken-down 시간이 달력 시간으로 표현될 수 없다면, mktime은 (time_t)(-1)의 값을 반환하고 brokentime의 내용을 갱신할 수 없다. 호출된 mktime은 또한 현재의 시간대에 대한 정보로 변수 tzname 를 설정한다. 17. 2. 6절 [Time Zone Functions] 참조.

 

17. 2. 4 형식화된 날짜와 시간

이 절에 설명된 함수들은 문자열로 시간값들을 형식화한다. 이들 함수들은 헤더파일 'time. h'에 선언되어 있다.

함수 : char *asctime(const struct tm *brokentime)

asctime 함수는 brokentime이 가리키고 있는 broken-down 시간을 표준 형식을 가진 문자열로 변환한다.
"Tue May 21 13: 46: 22 1991\n"
주안에 있는 요일의 약자는: `Sun', `Mon', `Tue', `Wed', `Thu' `Fri' 그리고 `Sat' 이다.
달들의 약자는: '`Jan', `Feb', 'Mar', 'Apr', 'May', Jun', 'Jul', 'Aug', 'Sep', 'Oct', Nov', 그리고'Dec' 이다.
반환값은 어떤 날짜와 시간 함수들의 호출에 의한 결과로 덮어쓰기가 된, 정적으로 할당된 문자열을 가리킨다. (그러나 어느 다른 함수도 이 문자열의 내용에 덧씌우기를 할 수 없다. )

함수 : char *ctime(const time_t *time)

ctime함수는 시간값이 달력시간(지역시간) 형식으로 지정되었다는 것을 제외하고는, asctime과 유사하다. 그것은 asctime(localtime (time))과 같다. ctime는 localtime으로 하기때문에 변수 tzname을 설정한다. 17. 2. 6절 [Time Zone Function] 참조.

함수 : size_t strftime(char *s, size_t size, const char *template, const struct tm *brokentime)

이 함수는 sprintf 함수(7. 11절 [Formatted Input] 참조)와 유사하지만, 형식 템플릿 template안에 나타날 수 있는 변환지정은 시간 변환을 위해서 정해진 현재의 지역시간에 따른 brokentime의 날짜와 시간의 요소들을 프린트하도록 특별화되었다. (19장 [Locales] 참조. ) template안에 나타난 보통의 문자들은 출력 문자열 s에 복사되어 진다; 이것은 다중 바이트 문자들로 이루어진 열들을 포함할 수 있다. 변환지정자는 `%'문자 다음에 나타나고, 다음처럼 출력 문자열을 조정한다.
 

%a : 현재의 지역에 맞는 약자로 표현된 요일이름.

%A : 현재지역에 맞는 완전한 요일이름.

%b : 현재지역에 맞는 약자인 달 이름.

%B : 현재지역에 맞는 완전한 달 이름.

%c : 현재 지역을 위해 선택된 날짜와 시간 표현.

%d : 십진수로 표현된(01에서 31까지의 범위) 한달 안의 날짜.

%H : 24시간 시계를 사용해서(00에서 23까지의 범위), 십진수로 나타낸 시간.

%I : 12시간 시계를 사용해서(01에서 12까지의 범위), 십진수로 나타낸 시간.

%j : 십진수(001에서 366까지의 범위)로 표현된 일년안의 날수.

%m : 십진수(01에서 12까지의 범위)로 표현된 달.

%M : 십진수로 표현된 분.

%p : 주어진 시간값에 맞는, `am'또는 `pm' 또는 현재지역에 맞는 연관된 문자열.

%S : 십진수로 표현된 초.

%U : 첫 번째 주의 첫 번째 날인 첫 번째 일요일을 기점으로 해서, 십진수로 표현된 올해의 주의수

%W : 첫 번째 주의 첫 번째날인 첫 번째 월요일을 기점으로 해서, 십진수로 표현된 올해의 주의 수

%w : 일요일을 0으로 한, 십진수로 표현된 요일.

%x : 시간 없이, 현재지역을 위해 예약된 날짜 표현.

%X : 날짜 없이, 현재지역을 위해 예약된 시간 표현.

%y : 세기(century)없이(00에서 99까지의 범위), 십진수로 표현된 연도.

%Y : 세기를 포함해서, 십진수로 표현된 연도.

%Z : 시간대나 이름 또는 약자(시간대가 결정될 수 없다면 비워라)

%% : 문자 `%'

size 인수는 널 종료문자를 포함해서, 배열 s에 저장된 문자들의 최대 개수를 나타내기 위해서 사용될 수 있다. 만일 형식화된 시간이 size 크기보다 더 많은 문자들이 필요하다면, 초과되는 문자들은 버려진다. strtime을 통한 반환값은 널 종료문자를 포함하지 않은, 배열 s에 저장된 문자들의 개수이다. 만일 value가 size와 같다면, 그 배열이 너무 작았음을 의미한다; 당신은 배열을 크기를 크게 하고, strtime를 재 호출하라. 만일 s가 널 포인터라면, strftime은 실제로 아무 것도 쓰지 않지만, 대신에 쓰여졌던 문자들의 개수를 반환한다. strftime에 대한 예는 17. 2. 7절 [Time Functions Example] 참조.

 

17. 2. 5 TZ으로 시간대를 정하기

GNU 시스템에서, 사용자는 TZ 환경변수로 시간대를 정할 수 있다. 환경변수를 어떻게 설정하는가에 대한 정보는, 22. 2절 [Environment Variables] 참조. 시간대를 억세스하기 위한 함수는 'time. h'에 선언되어 있다. TZ 변수의 값은 세 가지 형식중에 하나가 된다. 첫 번째 형식은 지역시간대에서 일광절약시간(또는 썸머타임)이 없는 곳에서 사용된다:

std offset

std 문자열은 시간대의 이름을 정한다. 그것은 세 개 이상의 문자열의 길이를 가져야만 하고, 콜론이 선행되거나, 숫자, 콤마, 또는 플러스나 마이너스 부호가 들어가 있으면 안 된다. 지역시간대 이름 사이에 공백이 없어야한다. 이러한 제한들은 정확하게 그 지정을 분석하기 위해 필요하다. offset는 협정 세계시간을 얻기 위하여 지역시간에 더해야만 하는 시간값을 정한다. 그것은 [+|-]hh[: mm[: ss]]와 같은 구문이다. 이것은 만일 지역시간대가 그리니치 자오선(Prime Meridian)의 서쪽에 있다면 양수이고, 동쪽에 있다면 음수이다. 시간은 0과 24의 사이에 있어야만 하고, 분과 초는 0과 59의 사이에 있어야만 한다.
예를 들어, 일광절약시간을 택하지 않고, 동부표준시간을 어떻게 정하는지는 다음과 같다.
EST+5
일광절약시간이 있는 곳에서 사용되는 두 번째 형식:

std offset dst [offset], start[/time], end[/time]

처음의 std 와 offset은 위에 설명된 것처럼 표준시간 대를 정한다. dst 문자열과 offset은 일광절약시간의 시간대에 맞는 name과 offset을 정한다; 만일 offset을 생략하면, 디폴트로 표준시간보다 한시간 앞으로 정해진다.
지정자의 나머지는 일광절약시간이 있는 곳에서의 설명이다. 일광절약 시간이 영향을 미칠 때는 시작필드에 있고, 다시 표준시간으로 변환되었을 때는 끝 필드에 있다. 다음 형식들은 이들 필드를 위한 설명이다.

Jn

이것은 1과 365사이에 있는 어떤 날 n으로, 율리우스력의 날짜를 정한다. 윤년에 있는 2월 29일은 더해지지 않는다.

n

0과 365사이에 있는 어떤 날 n으로, 율리우스력의 날짜를 정한다. 윤년에 있는 2월 29일은 더해진다.

Mm. w. d

m달의 w주의 d날. 날 d는 0(일요일)과 6사이의 값이어야 한다. 주 w는 반드시 1과 5사이이다; 주 1은 그 달에서 날 d가 발생한 첫 번째 주이고, 주 5는 달에서 마지막날 d가 있는 마지막 주이다. 달 m은 1과 12사이이다. time필드들은 지역시간을 다른 시간표현으로 변환할 때 지정한다. 만일 생략되면, 디폴트값은 02: 00: 00이다. 예를 들어, 미국에서 적당한 일광절약시간이 포함된 날짜로 동부시간대를 지정하는 것이 있다. 보통 GMT로부터의 offset는 5시간이다; 그리니치 자오선으로부터 서쪽으로 있기 때문에 양수 값이다. 썸머타임은 4월 첫 번째 일요일 오전 2시에 시작되고, 10월 마지막 일요일 오전 2시에 끝난다.

EST+5EDT, M4. 1. 0/M10. 5. 0

특별한 어느 지역에서 일광절약시간의 예정은 해마다 변경된다. 정확하게 하려면, 그 지역에 맞는 일광절약시간의 예정에 기초하여 날짜와 시간을 변경해야한다. 그렇지만, 시스템은 그 예정이 어떻게 변경되었는지를 당신이 지정할 도구들을 가지고 있지 않다. 당신이 이것을 할 수 있는 가장 좋은 방법은 하나의 특별한 예정을 지정해서 하는 것이다. 보통 현재의 시간을 표시하고 아무런 문제가 없을 때, 이것은 다른 날짜로 변경하기 위해 사용된다.

세 번째 형식은 이와 같다.

: characters

각각의 운영체제마다 이 형식을 다르게 해석한다. GNU C 라이브러리에서는, 문자들은 시간대를 표현하는 파일의 이름으로 해석한다. 만일 TZ 환경변수가 아무런 값도 가지고 있지 않다면, 그 오퍼레이션은 디폴트로 시간대를 정한다. 각 운영체제는 디폴트시간대를 정하기 위한 자신 나름대로의 규칙을 갖고 있고, 그래서 우리가 그들에 대해서 말할 수 있는 것은 적다.

 

17. 2. 6 시간대를 위한 함수와 변수들

변수 : char *tzname[2]

tzname 배열은 사용자가 선택한 표준 시간대와 일광절약시간대의 이름들을 표준 세-문자로 가진 두 개의 문자열을 저장한다. tzname[0]은 표준시간대(예를 들어 "EST")의 이름이고, tzname[1]은 일광절약시간이 사용될 때 시간대를 위한 이름이다(예를 들어, "EDT"). 이들은 TZ 환경변수로부터 std 와 dst문자열과 같다. tzname 배열은 tzset, ctime, strftime, mktime, 또는 localtime이 호출될때마다 TZ 환경변수로 초기화된다.

함수 : void tzset(void)

tzset함수는 TZ 환경변수의 값으로 tzname변수를 초기화한다. 이것은 시간대에 의존하는 다른 시간 변환 함수들에서 사용될 때 자동적으로 호출되기 때문에 당신이 직접 당신의 프로그램을 통해서 이것을 부를 필요가 없을 것이다.

다음의 변수들은 유닉스 시스템 V와의 호환성을 위해서 정의되었다. 이들 변수들을 localtime 함수를 호출함으로써 설정된다.

변수 : longint timezone

이것은 그리니치 표준시와 지역 표준 시간사이의 차이를 초단위로 저장한다. 예를 들어, 미국에서 동부시간대의 값은 5*60*60이다.
역자주 : 아까 동부시간대가 그리니치 표준시와 5시간의 차이가 난다고 했으니까. . . 5*60*60.

변수 : int daylight

이 변수는 만일 표준 미국 일광절약시간 규칙이 적용된다면 0이 아닌 값을 가진다.

 

17. 2. 7 시간 함수들의 예제

지역시간과 달력시간 함수들의 몇가지를 사용하는 예를 보여주는 프로그램이다.

#include <time. h>
#include <stdio. h>
#define SIZE 256
int
main (void)
{
char buffer[SIZE];
time_t curtime;
struct tm *loctime;
/* 현재의 시간을 얻어라 */
curtime = time (NULL);
/* 지역시간 표현으로 변환하라 */
loctime = localtime (&curtime);
/* 표준 형식으로 날짜와 시간을 출력하라. */
fputs (asctime (loctime), stdout);
/* 보기 좋은 형식으로 그것을 출력하라 */
strftime (buffer, SIZE, "Today is %A, %B %d. \n", loctime);
fputs (buffer, stdout);
strftime (buffer, SIZE, "The time is %I: %M %p. \n", loctime);
fputs (buffer, stdout);
return 0;
}
다음과 같은 출력을 만들어낸다.
Wed Jul 31 13: 02: 36 1991
Today is Wednesday, July 31.
The time is 01: 02 PM.


17. 3 알람을 설정하기

alarm 과 setitimer 함수들은 어떤 미래의 시간에 프로세스 그 자체에 인터럽트를 거는 메커니즘을 제공한다. 그들은 타이머를 설정함으로써 이루어진다. 타이머가 끝나면, 프로세스는 신호를 받는다.

각 프로세스는 유용한 세 가지 독립 간격 타이머를 갖는다.

시계 시간을 계산하는 실제-시간 타이머. 이 타이머는 그 시간이 경과되면 프로세스에게 SIGALRM 신호를 보낸다.

프로세스에 의해 사용된 CPU시간을 셈하는 가상 타이머. 이 타이머는 그 시간이 경과되면 프로세스에게 SIGVTALRM 신호를 보낸다.

profiling 타이머는 프로세스에 의해 사용된 CPU 시간과 프로세스를 위한 시스템 호출에서 사용된 CPU 시간 양쪽을 계산한다.

이 타이머는 그 시간이 경과되었을 때, 프로세스에게 SIGPROF 신호를 보낸다.

당신은 어떤 종류로 설정된 어느 주어진 시간에 한가지의 타이머만을 사용할 수 있다. 만일 당신이 아직 경과되지 않은 시간을 가진 타이머를 설정하면, 그 타이머는 새로운 값으로 간단히 재설정된다. 당신은 setitimer 이나 alarm을 호출하기 전에 signal이나 sigaction을 사용해서 적당한 알람 신호를 위한 핸들러를 만들어야 할 것이다. 그렇지 않다면, 시간이 경과되었을 때 발생할 수 있는 사건들의 연결은 알람 신호들에 대한 디폴트 동작으로, 프로그램의 종결을 발생시킬 것이다. 21장. [Signal Handling] 참조.

setitimer 함수는 알람을 설정하기 위해서 주요한 방법이다. 이 도구는 헤더파일 `sys/time. h'에 선언되어 있다. 실제-시간 타이머를 설정하기 위해서 간단한 인터페이스를 제공하는 alarm 함수는 `unistd. h'에 선언되어 있다.

데이터타입 : struct itimerval

이 구조체는 타이머가 경과되는 때는 정하기 위해서 사용되어진다. 그것은 다음과 같은 멤버들을 포함하고 있다.

struct timeval it_interval

이것은 연속적인 타이머 인터럽트들 사이의 간격이다. 만일 0이면, alarm은 오직 한 번만 보내질것이다.

struct timeval it_value

이것은 첫 번째 타이머 인터럽트 간격이다. 만일 0이면, 알람은 불가능하다. 데이터타입 struct timeval은 17. 2. 2절 [High-Resolution Calendar] 에 선언되어 있다.

함수 : int setitimer(int which, struct itimerval *old, struct itimerval *new )

setitimer 함수는 new에 따른 것에 의해 정해진 타이머를 설정한다. which 인수는 ITIMER_REAL, ITIMER_VIRTUAL, 또는, ITIMER_PROF 중의 한 값을 가질 수 있다. 만일 old가 널 포인터가 아니라면, setitimer 은 그것이 가리키고 있는 구조체에 같은 종류의 전에 경과되지 않았던 어느 타이머에 대한 정보를 반환한다.
성공하면 반환값은 0이고, 실패하면 -1이다. 다음의 errno는 이 함수를 위해 정의된 에러상황이다.

EINVAL : 타이머의 간격이 너무 길었다.

함수 : int getitimer(int which, struct itimerval *old)

getitimer 함수는 old가 가리키고 있는 구조체에 의해 정해진 타이머에 대한 정보를 저장한다.
반환값과 에러상황들은 setitimer와 같다.

ITIMER_REAL

이 상수는 실제-시간 타이머로 정하기 위해서, setitimer와 getitimer 함수들에서 which 인수로써 사용될 수 있다.

ITIMER_VIRTUAL

이 상수는 가상 타이머로 정하기 위해서, setitimer와 getitimer 함수들에서 which 인수로써 사용될 수 있다.

ITIMER_PROF

이 상수는 profiling 타이머로 정하기 위해서, setitimer와 getitimer 함수들에서 which 인수로써 사용될 수 있다.

함수 : unsigned int alarm(unsigned int seconds)

alarm 함수는 초단위로 seconds가 경과되도록 실제-시간 타이머를 설정한다. 만일 당신이 현존하는 alarm을 취소하길 원한다면, 당신은 seconds인수를 0으로 해서 alarm을 호출하면 된다. 반환값은 미리 호출됐던 alarm에서 몇초가 남았는지를 가리킨다. 만일 미리 호출된 alarm이 없다면, alarm은 0을 반환한다. alarm함수는 이처럼 setitimer에 의하여 정의될 수 있다.
unsigned int alarm (unsigned int seconds)
{
struct itimerval old, new;
new. it_interval. tv_usec = 0;
new. it_interval. tv_sec = 0;
new. it_value. tv_usec = 0;
new. it_value. tv_sec = (long int) seconds;
if (setitimer (ITIMER_REAL, &new, &old) < 0)
return 0;
else
return old. it_value. tv_sec;
}
alarm 함수를 사용하는 예는 21. 4. 1절 [Handler Returns] 에서 보여주고 있다. 만일 당신이 주어진 시간(초단위의)동안 당신의 프로세스가 기다리기를 원한다면 sleep 함수를 사용할 수 있을 것이다. 17. 4절[Sleeping] 참조.
당신은 타이머가 경과되었을 때, 정확하게 도착된 신호를 셀 수 없을 것이다. 멀티프로세싱 환경에서는 어느 정도의 지연이 있기 때문이다.
 
이식성 노트: setitimer 와 getitimer 함수들은 BSD Unix로부터 왔고, alarm 함수는 POSIX. 1 표준으로 정해져있다. setitimer 은 alarm보다는 더 강력하지만, alarm이 더 광범위하게 쓰인다.


17. 4 Sleeping

sleep 함수는 짧은 시간동안 그 프로그램을 기다리게 하는 간단한 방법을 제공한다. 만일 당신의 프로그램이 신호들을 사용하지 않는다면( 종료를 제외하고), 당신은 sleep가 정해진 시간동안에 확실하게 기다린다는 것을 기대할 수 있다. 그렇지 않다면, sleep는 만일 신호가 도착한다면 곧바로 반환될 수 있다; 만일 당신이 신호에 상관없이 주어진 시간동안 기다리기를 원한다면 select( 8. 6절 [Waiting for I/O] 참조. )를 사용하고, 기다리는 어떠한 기술자도 지정하지 말아라.

함수 : unsigned int sleep (unsigned int seconds)

sleep 함수는 seconds동안 기다리거나, 첫 번째 발생한 신호가 도착될 때까지 기다린다. 만일 sleep 함수가 요청된 시간이 경과되었기 때문에 반환했다면, 반환값은 0이다. 만일 신호가 도착되어서 반환했다면, 그 반환값은 아직 경과되지 않고 남은 시간의 값이다. sleep 함수는 `unistd. h'에 선언되어 있다.
sleep가 0이 아닌 값을 반환했을 때, 그 반환값을 사용해서 정해진 시간동안 다시 기다리도록 sleep를 재호출하려는 유혹에 저항하라. 이것은 빈번하게 도착한 신호들만큼 정확하게 길어진 어떤 시간동안 작업할 것이다. 그러나 각 신호는 그 부가적인 시간(초)으로 인해서 원래 정해진 기다림의 시간보다 길어지게 할 것이다.
기다림이 얼마나 길어지거나, 짧아질 수 있는지에 대한 아무런 제한이 없는 어떤 신호들이 불행하게도 빠르게 연속적으로 발생한다고 가정하라. 대신에, 그 프로그램이 기다림을 멈추게 된 그 시간을 계산하고, 다시 남아있는 시간동안 기다림을 다시 시도하도록 하라. 이것은 1초보다도 더 많이 시간차이가 나지 않을 것이다. 더 적은 시간동안 작업하려면, 당신은 select를 사용하고, 꽤 정확한 시간동안 기다리게 할 수 있다. ( 물론, 멀티유저 시스템에서 그 기계가 단지 한 응용프로그램을 위해서 사용되지 않는다면, 피할 수 없는 부가적인 지연을 발생될 것이다, 당신이 그것을 피할 수 있는 방법은 아무 것도 없다. )
어떤 시스템상에서, 만일 당신의 프로그램에서 SIGALRM을 사용한다면 sleep는 이상하게 동작할 수 있다. 심지어 sleep가 호출되었을 때 SIGALRM 신호가 무시되거나 블록 된다면, sleep는 SIGALRM 신호 때문에 시기상조적으로 반환될 것이다. 만일 당신이 프로세스가 기다리고 있는(sleeping)동안 배달된 SIGALRM 신호와 SIGALRM 신호를 위한 핸들러를 만들었다면, 그 동작은 당신이 만든 신호 핸들러에 그 처리를 맡기는 대신에 sleep의 반환을 발생시킬 것이다. 그리고 만일 sleep가 alarm을 요청하거나 SIGALRM의 처리를 선택하는 핸들러가 가진 신호에 의해 인터럽트 된다면, 이 핸들러와 sleep는 방해될 것이다. GNU 시스템에서는, sleep가 SIGALRM에 의하여 작업하지 않기 때문에, sleep와 SIGALRM을 같은 프로그램에서 사용하는 것이 안전하다.


17. 5 자원 사용

함수 getrusage 와 데이터타입 struct rusage는 프로세스의 사용형태를 시험하기 위해서 사용된다. 그들은 `sys/resource. h'에 선언되어 있다.

함수 : int getrusage(int processes, struct rusage *rusage)

이 함수는 processes에 의해 정해진 그 프로세스를 위해 사용된 것을 *rusage에 정보를 저장하여, 보고한다. 대부분의 시스템에서, processes는 오직 두 개의 유용한 값을 가진다:

RUSAGE_SELF

단지 현재의 프로세스.

RUSAGE_CHILDREN

이미 종료된 모든 자식 프로세스(직접 과 간접).
GNU 시스템에서, 프로세스 ID를 정함으로 해서, 특정한 자식 프로세스에 대해서 조사할 수 있다. getrusage의 반환값은 성공하면 0이고, 실패하면 -1이다.

EINVAL

processes 인수가 유용하지 않다.

특정한 자식 프로세스를 위한 사용형태를 얻는 방법은 wait4 함수를 통해서 할 수 있는데, 그 함수는 자식 프로세스가 종료되었을 때 자식 프로세스를 위한 모든 것을 반환한다. 23. 8절 [BSD Wait Functions] 참조.

데이터타입 : struct rusage

이 데이터타입은 다양한 종류의 자원에 대한 사용량을 기록한다. 이것은 다음과 같은 멤버들을 갖으며, 다른 것도 가능하다.
struct timeval ru_utime : 사용된 사용자 시간.
struct timeval ru_stime : 사용된 시스템 시간.
long ru_majflt : 폴트의 개수.
long ru_inblock : 블록된 입력 명령의 개수.
long ru_oublock : 블록된 출력 명령의 개수.
long ru_msgsnd : 보냈던 메시지의 개수.
long ru_msgrcv : 받았던 메시지의 개수.
long ru_nsignals : 받았던 시그널의 개수.

사용형태를 시험하는 함수로는 vtimes도 있지만 여기서 설명하지는 않는다. 그것은 `sys/vtimes. h'에 선언되어 있다.


17. 6 제한된 자원 사용

당신은 프로세스의 자원 사용에 대해서 제한을 가할 수 있다. 그 프로세스가 제한을 넘어서려 시도할 때, 제한에 따라서 그 프로세스는 신호를 받거나, 아니면 시도했던 것의 실패로 인한 시스템 호출이 될 것이다. 각 프로세스는 그 부모 프로세스로부터 처음에는 제한을 상속받지만, 그후에는 그들을 변경 할 수 있다. 이 절에 있는 심볼들은 `sys/resource. h'에 정의되어 있다.

함수 : int getrlimit(int resource, struct rlimit *rlp)

자원 resource의 현재값과 최대 값을 읽고, 그들을 *rlp에 저장한다. 성공하면 반환값은 0이고 실패하면 -1이다. 발생 가능한 에러 상황은 EFAULT뿐이다.

함수 : int setrlimit(int resource, struct rlimit *rlp)

*rlp에 있는 것으로 자원 resource의 현재값과 최대 값을 설정한다. 성공하면 반환값은 0이고 실패하면 -1이다. 다음의 errno는 가능한 에러상황이다.

EPERM

당신이 허용된 최대 제한값을 변경하려 시도했지만, 당신은 그렇게 할만한 특권을 부여받지 않았다.

데이터타입 : struct rlimit

이 구조체는 제한 값들을 받기 위해서 getrlimit에서 사용되고, 제한 값들을 정하기 위해서 setrlimit에서 사용된다. 두 개의 필드를 갖는다.

rlim_cur : 질문에 대한 제한의 현재값.

rlim_max

질문에 대한 제한의 최대 허용값. 당신은 이 최댓값 보다 큰 수로 제한의 현재값을 설정할 수 없다. 오직 슈퍼 유저만이 최대 허용값을 변경할 수 있다.

getrlimit에서 그 구조체는 출력으로서, 현재값들을 받는다. setrlimit에서 그 구조체는 새로운 값들을 정하는데 사용된다. 당신이 제한을 정할 수 있는 자원의 리스트이다. 그들은 바이트로 계산된 크기이다.

RLIMIT_CPU

그 프로세스가 사용할 수 있는 cpu time의 최대량. 만일 이것보다 더 길게 실행한다면, SIGXCPU라는 신호가 발생한다. 값은 초단위로 계산된 것이다. 21. 2. 7절 [Nonstandard Signals] 참조.

RLIMIT_FSIZE

그 프로세스가 만들 수 있는 파일의 최대 크기. 이것보다 큰 파일을 만들려하면 SIGXFSZ라는 신호가 발생된다. 21. 2. 7절 [Nonstandard Siganls] 참조.

RLIMIT_DATA

프로세스가 사용할 수 있는 데이터 메모리의 최대크기. 만일 그 프로세스가 이 양을 초과하는 데이터 메모리를 할당하려 시도하면 그 할당은 실패한다.

RLIMIT_STACK

프로세스를 위한 최대 스택 크기. 만일 프로세스가 이 크기보다 크게 스택을 확장하려 시도한다면, SIGSEGV 신호가 발생된다. 21. 2. 1절 [Program Error Signals] 참조.

RLIMIT_CORE

이 프로세스가 만들 수 있는 최대 크기 코어 파일. 만일 프로세스가 종료되고 코어파일이 만들어졌고, 이 최대크기가 충분하지 않다면, 코어 파일은 잘려진다.

RLIMIT_RSS

이 프로세스가 얻을 수 있는 물리적 메모리의 최대량. 이 수치는 시스템 스케줄러와 메모리 할당자를 위한 정보가 된다; 시스템은 메모리가 남아있는 양이 있을 때 그 프로세스에게 더 많은 메모리를 줄 수도 있다.

RLIMIT_OPEN_FILES

프로세스가 개방할 수 있는 파일의 최대개수. 만일 이것보다 더 많이 개방하려 한다면, EMFILE라는 에러코드가 발생된다. 2. 2절 [Error Codes] 참조.

RLIM_NLIMITS

다른 자원 제한의 개수. 어느 유용한 자원 피연산자는 RLIM_NMLIMITS보다 적을 것임이 틀림없다.

상수 : int RLIM_INFINITY

이 상수는 setrlimit에서 제한 값으로 사용될 때 "무한대"의 값을 나타낸다.
자원 제한을 설정하는 함수는 ulimit와 vlimit가 있지만 여기서 설명되지 않았다. vlimit는`sys/vlimit. h'에 선언되어 있고 BSD로부터 왔다.


17. 7 프로세스 우선권

여러개의 프로세스들이 실행하려 시도될 때, 그들 각각이 가진 우선권이 그 프로세스가 가져갈 CPU의 분할을 결정한다. 이 절은 당신이 어떻게 프로세스의 우선권을 알아내고 설정할 수 있는지를 설명한다. 이들 함수들과 매크로 모두는 `sys/resource. h에 선언되어 있다.

유용한 우선권 값들의 범위는 운영체제에 의존되지만, 일반적으로 -20에서 20까지에서 실행된다. 낮은 우선권 값은 그 프로세스가 더 자주 실행됨을 의미한다. 이들 상수들은 우선권 값들의 범위를 설명한다.

PRIO_MIN

유용한 우선권의 가장 작은 값.

PRIO_MAX

유용한 우선권의 가장 큰 값.
** 역자주 : 원서에는 PRIO_MAX에 The smallest라고 되어 있었습니다. 하지만 저는 틀렸다는 판단을 갖고 largest라고 고쳤음을 알려 드립니다.

함수 : int getpriority(int class, int id)

프로세스들 class의 우선권을 읽는다; class와 id는 밑에 있는 것 중에 한가지로 정한다.
성공하면 반환값을 우선권 값이고, 실패하면 -1을 반환한다. 다음의 errno는 이 함수에서 가능한 에러상황이다.

ESRCH

class와 id의 조합이 현존하고 있는 어떤 프로세스와도 맞지가 않는다.

EINVAL

class의 값이 유용하지 않다.
반환값이 -1일 때, 그것은 실패했음을 알리거나, 또는 그것이 우선권의 값이 될 수 있다. 이럴때를 대비한 정확한 방법은 getpriority를 호출하기 전에 errno = 0으로 설정을 해놓으면, 실패를 판단하는 조건으로 errno != 0 을 사용할 수 있다.

함수 : int setpriority(int class, int id, int priority)

프로세스들 class의 우선권을 읽는다(설정한다. ); class 와 id는 밑에 것 중에 하나로 설정한다.
성공하면 반환값은 0이고 실패하면 -1이다. 다음의 errno는 이 함수를 위해 정의된 에러상황이다.
 
** 역자주 : 역시 이곳에서도 문맥상 Read가 맞지가 않습니다. 책에는 Read라고 나와있지만, 함수 이름이나, 다음 문장들을 참고로 보건대 저는 Set이 맞다고 생각합니다.

ESRCH : class와 id의 조합이 현존하는 어떤 프로세스와도 맞지가 않는다.

EINVAL : class의 값이 유용하지 않다.

EPERM

당신이 다른 사용자의 프로세스의 우선권을 설정하려 시도하였고, 당신은 그것을 위한 특권을 가지지 않았다.

EACCES

당신이 어떤 프로세스의 우선권을 낮추려 시도했고, 당신은 그것을 할만한 특권이 부여되지 않았다.
인수 class와 id는 함께 당신이 우선권을 읽거나, 설정할 프로세스의 집합을 설정한다. 이들은 class에서 사용할 수 있는 값들이다.

PRIO_PROCESS

한 프로세스의 우선권을 읽거나 설정하라. 인수 id는 프로세스의 ID이다.

PRIO_PGRP

한 프로세스 그룹의 우선권을 읽거나 설정하라. 인수 id는 프로세스 그룹 ID 이다.

PRIO_USER

한 사용자의 프로세스들의 우선권을 읽거나 설정하라. 인수 id는 사용자 ID이다.
만일 인수 id가 0이면, class에 따라서 현재 프로세스, 현재 프로세스 그룹 또는 현재 사용자를 나타낸다.

함수 : int nice(int increment)

increment로 현재 프로세스의 우선권을 증가시킨다. 반환값은 의미가 없다. 다음은 nice함수와 같은 일을 하는 함수이다. 즉. . nice의 정의이다.
int nice (int increment)
{
int old = getpriority (PRIO_PROCESS, 0);
setpriority (PRIO_PROCESS, 0, old + increment);
}