: busy waiting使使

素朴な実装手法とその問題点

編集

 (nop : No OPeration)CPUnopCPUnop調nop使nop

CPUnop1調使CPUnop使CPU

SMPCPUCPU

C言語でのコード例

編集

以下のPOSIXスレッドライブラリを使ったC言語コードでは、複数のスレッドグローバル変数によるフラグを共有している。1番目のスレッドはビジーウェイトでフラグの値の変化を待っている。

#include <stdatomic.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

/* 全関数から見えるグローバルフラグ変数 */
atomic_int g_flag;

/* スレッド#1はフラグが偽 (0) になることをスピンして待つ */
static void *thread_func1(void*) {
    while (g_flag) {
        /* 何もしない - 単にチェックしながら回り続ける */
    } 
    printf("Thread#1 received notification: value of flag has been changed to %d.\n", g_flag);

    return NULL;
}

/* スレッド#2は一定時間待機した後にフラグを偽 (0) にする */
static void *thread_func2(void*) {
    sleep(60); /* 60秒間スリープ */
    g_flag = 0;
    printf("Thread#2 changed the value of flag to %d.\n", g_flag);

    return NULL;
}

int main(void) {
    int ret_code;
    pthread_t t1, t2;
    g_flag = 1; /* フラグを真にする */

    ret_code = pthread_create(&t1, NULL, thread_func1, NULL);
    if (ret_code != 0) {
        printf("Failed to create pthread #1.\n");
        return -1;
    }

    ret_code = pthread_create(&t2, NULL, thread_func2, NULL);
    if (ret_code != 0) {
        printf("Failed to create pthread #2.\n");
        return -1;
    }

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    printf("All pthreads finished.\n");
    return 0;
}

ccGCCClangUNIX:
$ cc -std=c11 spinlock.c -pthread

CC++volatileC/C++volatile使使[1] (mutex)  (condition variable) 使C11C++11使

JavaC#volatile[2][3]

CPU の利用状況

編集

2602

UNIXtop  uptime 使CPU:
$ uptime; ./a.out ; uptime
13:25:47 up 53 days, 23:50,  4 users,  load average: 0.00, 0.00, 0.00
Thread#2 changed the value of flag to 0.
Thread#1 received notification: value of flag has been changed to 0.
All pthreads finished.
13:26:47 up 53 days, 23:51,  4 users,  load average: 0.75, 0.21, 0.07

 0.00  0.75  1.00 1100%

ビジーウェイトの代替手法

編集

12CPU

使CPUCPUCPU

ビジーウェイトが適している状況

編集

CPU

脚注

編集

関連項目

編集

外部リンク

編集