C言語システムコール-nanosleep

nanosleepシステムコール

概要

nanosleepはナノ秒単位の指定時間でプロセスを停止します。

LinuxなどのOSでは、Cライブラリのsleep()やusleep()は内部的にnanosleepシステムコールを呼び出す実装となっています。


nanosleepを実行すると、シグナルが到着した時以外には時間経過するまで処理をリターンしません。

シグナル到着によってnanosleepが中断した場合、戻り値が-1となり、errnoにEINTRが設定されます。


サンプルプログラム

指定時間sleepします。

sleep中にSIGINT(Ctrl+c)を受信すると、残りのsleep時間を表示します。



#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <time.h>

/*!
 * @brief    シグナル用のダミー関数
 */
static void
dummy_func(int sig)
{
    return;
}

/*!
 * @brief     プロセスを停止する
 * @param[in] sec  秒数
 * @return    0:success/-1:failure
 */
static int
sleep_process(int sec)
{
    struct timespec req = {0};
    struct timespec rem = {0};
    int rc = 0;

    /* SIGINT(Ctrl+c)にダミー処理を設定する */
    if(signal(SIGINT, dummy_func) == SIG_ERR){
        printf("Error: signal() %s\n", strerror(errno));
        return(-1);
    }

    req.tv_sec  = (time_t)sec;
    req.tv_nsec = 0;
    while(1){
        rc = nanosleep(&req, &rem);
        if(errno == EINTR){
            /* SIGINT受信で残りsleep時間を表示する */
            printf("%ld.%09ld(sec)\n", (long)rem.tv_sec, (long)rem.tv_nsec);
            req = rem;
        }else if(rc == 0){
            /* 正常終了 */
            break;
        }else if(rc < 0){
            /* エラー終了 */
            printf("Error: nanosleep() %s\n", strerror(errno));
            return(-1);
        }
    }

    return(0);
}

int
main(int argc, char *argv[])
{
    int rc = 0;

    if(argc != 2){
        fprintf(stderr, "Usage: %s <time(sec)>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    rc = sleep_process(atoi(argv[1]));
    if(rc != 0) exit(EXIT_FAILURE);

    exit(EXIT_SUCCESS);
}

関連ページ