マルチスレッド面接問題分析(出力順序制御)

1917 ワード

プログラムを作成し、3つのスレッドを開き、この3つのスレッドのIDはそれぞれA、B、Cであり、各スレッドは自分のIDを画面に10回印刷し、出力結果はABCの順序で表示しなければならない.如:ABCABC....順番に押す.
#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <string.h> 
#define DEBUG 1 
  
int num = 0; 
pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t qready=PTHREAD_COND_INITIALIZER;

void* thread_func(void *arg)
{
    int param = (int) arg;
    int i;
    
    for(i = 0; i < 10; i++)
    {
        pthread_mutex_lock(&mylock);
        
        while(param != num)
            pthread_cond_wait(&qready, &mylock);
        
        printf("%c", param + 'A');
        num = (num + 1) % 3;
        
        pthread_mutex_unlock(&mylock);
        pthread_cond_broadcast(&qready);
    }
    
    return (void *)0;
}

int main()
{
    int i;
    pthread_t tid[3];
    void *tret;
    
    for(i = 0; i < 3; i++)
        pthread_create(&tid[i], NULL, thread_func, (void *) i);
    for(i = 0; i < 3; i++)
        pthread_join(tid[i], &tret);    
}

まず,a,b,cの3つのサブスレッドを開き,そのうちaは「A」を印刷し,bは「B」を印刷し,cは「C」を印刷する.次にabcは実行を開始し、まずa,b,cはいずれもロックを試み、そのうちの1つはロックに成功し、他の2つはブロックして待っていた.bロックが成功したと仮定してもいいです(実はこれはaロックを制御して先にロックに成功することができます).このときaスレッドとcスレッドはロック待ちでブロックされ、bスレッドは実行を開始し、while(param!=num)に実行すると、彼のparamは1なので!=num(0)なので、次の条件変数待機文を実行し、現在のロックを一時的に解放し、条件変数qreadの上に待機します.このときbがロックを解放すると,aとcスレッドがループに入る機会があるからである.cがロックを得た場合,彼の状態はbと同様に条件変数の上にブロックされることが分かった.条件変数にはキューがあります.
c b
このときaは、aスレッドで条件変数を実行せずに待機し、「A」を印刷してnumを1にすることで、bスレッドを実行させることができるので、次の文を実行することができます.そしてaスレッドはロックを解放し、条件変数にブロックされているすべてのスレッド(pthread_cond_broadcast(&qready);)を起動し、そしてbもcも目が覚めた.そこでもう一度ロックを奪い取って、cがロックを奪ったと仮定して、それから彼はもう一度傷つけられた.彼はwhile文の中の条件変数を実行して待つ必要があるからだ.この時の条件変数はaとcスレッドをブロックし、cは再びブロックされ、当然のbがスレッドを実行して「B」を印刷し、後の物語は同じになった.
これにより、スレッドの出力順序を効果的に制御できます!