マルチスレッドのプログラミング

「生産者 / 消費者」問題の例

例 8-2 では、「生産者 / 消費者」問題の生産者と消費者をそれぞれ別のプロセスで表現しています。メインルーチンは、0 に初期化されたメモリーを自分のアドレス空間にマッピングし、それを子プロセスと共有します。mutex_init()cond_init() を呼び出さなければならないのは、それらの同期変数のタイプが USYNC_PROCESS だからです。

子プロセスが 1 つ生成され、消費者の処理が実行されます。親プロセスは生産者の処理を実行します。

この例では、生産者と消費者を呼び出す各駆動ルーチンも示しています。producer_driver()stdin から文字を読み込み、producer() を呼び出します。consumer_driver()consumer() を呼び出して文字を受け取り、stdout に書き出します。

例 8-2 のデータ構造は、条件変数による「生産者 / 消費者」のコーディング例のデータ構造と同じです (詳細は、「片方向リンクリストの入れ子のロック」を参照してください)。


例 8-2 「生産者 / 消費者」問題 − USYNC_PROCESS を使った例


main() {
    int zfd;
    buffer_t *buffer;

    zfd = open("/dev/zero", O_RDWR);
    buffer = (buffer_t *)mmap(NULL, sizeof(buffer_t),
        PROT_READ|PROT_WRITE, MAP_SHARED, zfd, 0);
    buffer->occupied = buffer->nextin = buffer->nextout = 0;

    mutex_init(&buffer->lock, USYNC_PROCESS, 0);
    cond_init(&buffer->less, USYNC_PROCESS, 0);
    cond_init(&buffer->more, USYNC_PROCESS, 0);
    if (fork() == 0)
        consumer_driver(buffer);
    else
        producer_driver(buffer);
}

void producer_driver(buffer_t *b) {
    int item;

    while (1) {
        item = getchar();
        if (item == EOF) {
            producer(b, `¥0');
            break;
        } else
            producer(b, (char)item);
    }
}

void consumer_driver(buffer_t *b) {
    char item;

    while (1) {
        if ((item = consumer(b)) == '¥0')
            break;
        putchar(item);
    }
}

子プロセスが 1 つ生成され、消費者の処理が実行されます。親プロセスは生産者の処理を実行します。