タイマー割り込みの作り方(複数のタイマーを使う)


子プロセスを2つfork()すると複数のタイマー割り込みが可能になります。
ソースは以下のとおりです。

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>
#include <time.h>
#include <signal.h>

int semid;

//排他処理の開始するためのロック
//自分よりも先にロックされていた場合にはロック解除されるまでスリープします
void lock(int semid){
    struct sembuf sb[1];
    sb[0].sem_num=0;
    sb[0].sem_op=-1;
    sb[0].sem_flg=0;
    if(EOF==semop(semid,sb,1)){
        printf("%s\n","lock ERR");
        exit(1);
    }
}
//排他処理の終了のためのロック解除
void unlock(int semid){
    struct sembuf sb[1];
    sb[0].sem_num=0;
    sb[0].sem_op=1;
    sb[0].sem_flg=0;
    if(EOF==semop(semid,sb,1)){
        printf("%s\n","unlock ERR");
        exit(1);
    }
}

int main(int argc, char **argv) {
    int i=1;
    pid_t result_pid1;
    pid_t result_pid2;
    int kill_status;
    int wait_status;
    time_t now;
    struct tm *pnow;
    int sem_value1=0;
    int sem_value2=0;

    //セマフォを割り付けます
    semid=semget(IPC_PRIVATE,3,0666);
    if(semid==EOF){
        printf("%s\n","semget ERR");
        exit(1);
    }
    //セマフォに初期値を書き込みます
    SemSetValue(semid,0,1);

    result_pid1 = fork();
    if (result_pid1 == 0) {
    // 子プロセス1開始 //
    // 1秒毎にセマフォをunlockする
        while (1) {
            sleep(1);
            SemSetValue(semid,1,1);
            unlock(semid);
        }
    }

    result_pid2 = fork();
    if (result_pid2 == 0) {
    // 子プロセス2開始 //
    // 5秒毎にセマフォをunlockする
        while (1) {
            sleep(5);
            SemSetValue(semid,2,1);
            unlock(semid);
        }
    }

    for(i=0;i<60;i++) {
        lock(semid); // Wait Unlock
        sem_value1 = semctl(semid, 1, GETVAL, 0);
        sem_value2 = semctl(semid, 2, GETVAL, 0);
        if(sem_value1 == 1) {
            now = time(NULL);
            pnow = localtime(&now);
            printf("%02d:%02d:%02d\n",pnow->tm_hour,pnow->tm_min,pnow->tm_sec);
            SemSetValue(semid,1,0);
        }
        if(sem_value2 == 1) {
            now = time(NULL);
            pnow = localtime(&now);
            printf("%s",asctime(pnow));
            SemSetValue(semid,2,0);
        }
    }

    //子プロセスをKILL
    kill_status = kill( result_pid1, SIGKILL );
    wait(&wait_status);

    kill_status = kill( result_pid2, SIGKILL );
    wait(&wait_status);

    //セマフォの削除
    if((semctl(semid,0,IPC_RMID,0))==EOF){
        printf("%s\n","ERR");
        exit(1);
    }

    exit(0);
}


実行結果を以下に示します。
1秒毎と5秒毎に2つの割り込みが発生し現在時刻を表示します。
$ ./Sample3
10:46:06
10:46:07
10:46:08
10:46:09
Sun Aug 10 10:46:10 2014
10:46:10
10:46:11
10:46:12
10:46:13
10:46:14
Sun Aug 10 10:46:15 2014
10:46:15
10:46:16
10:46:17
10:46:18
10:46:19
Sun Aug 10 10:46:20 2014
10:46:20
10:46:21
10:46:22
10:46:23
10:46:24
Sun Aug 10 10:46:25 2014

次はタイマー割り込みとボタン入力を同時に処理します。

続く