マルチスレッド面接問題分析(出力順序制御)
1917 ワード
プログラムを作成し、3つのスレッドを開き、この3つのスレッドのIDはそれぞれA、B、Cであり、各スレッドは自分のIDを画面に10回印刷し、出力結果はABCの順序で表示しなければならない.如:ABCABC....順番に押す.
まず,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」を印刷し、後の物語は同じになった.
これにより、スレッドの出力順序を効果的に制御できます!
#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」を印刷し、後の物語は同じになった.
これにより、スレッドの出力順序を効果的に制御できます!