いっしょにtalk C栗(第百一十九回:C言語例--スレッドデッドロック三)
皆さん、こんにちは、前回はスレッドのデッドロックの例を話しましたが、今回はこの例を続けてみましょう.余談はさておき,話は本筋に戻る.一緒にtalk C栗を食べましょう!
官たちは、紙面の都合で前回はデッドロックが発生した第1の原因だけを紹介しましたが、今日はデッドロックが発生した第2の原因を紹介し、その原因の偽コードを実際のC言語コードに変換します.
便宜上,前の章で反発量を示すコードを用いて,このコードに基づいていくつかの小さな修正を行い,デッドロックを実証した.コードは次のとおりです.
まず2つの反発量を定義し,反発量はグローバル変数であり,スレッドの使用を容易にする.
次に、メインプロセス(main関数)で2つの反発量を初期化します.
プライマリ・プロセスの最後に、反発量に関連するリソースを解放することも覚えておいてください.
2つのスレッドの実行関数をそれぞれ変更します.このセグメントコードはコアコードです.よく読んでください.
上記のプログラムを実行すると、次の結果が得られます.
上記のプログラムの実行結果から、スレッド1は反発量1をロックし、反発量2を待つことがわかる.スレッド2は、反発量2をロックし、反発量1を待つ.これによりデッドロックが発生し、プログラムの実行エラーが発生します.
このプログラムはデッドロックの原因を示すために書かれています.このようにプログラムを書くのは合理的ではありません.スレッドを同期できないので、プログラムの内容にこだわらないで、デッドロックがどのように発生したのかを理解することに重点を置いています.
官达を见て、本文の中でコードを书かないで、完成したコードは私の资源の中に置いて、みんなはここをクリックしてダウンロードして使うことができます.
皆さん、スレッドのデッドロックの例についてお話しします.後に何か例があるか知りたいので、次の分解を聞いてください.
官たちは、紙面の都合で前回はデッドロックが発生した第1の原因だけを紹介しましたが、今日はデッドロックが発生した第2の原因を紹介し、その原因の偽コードを実際のC言語コードに変換します.
便宜上,前の章で反発量を示すコードを用いて,このコードに基づいていくつかの小さな修正を行い,デッドロックを実証した.コードは次のとおりです.
まず2つの反発量を定義し,反発量はグローバル変数であり,スレッドの使用を容易にする.
#if MUTEX_ENABLE
pthread_mutex_t mutex_value1;
pthread_mutex_t mutex_value2;
#endif
次に、メインプロセス(main関数)で2つの反発量を初期化します.
res = pthread_mutex_init(&mutex_value1,NULL);
res = pthread_mutex_init(&mutex_value2,NULL);
プライマリ・プロセスの最後に、反発量に関連するリソースを解放することも覚えておいてください.
#if MUTEX_ENABLE
//destroy mutex
res = pthread_mutex_destroy(&mutex_value1);
res = pthread_mutex_destroy(&mutex_value2);
#endif
2つのスレッドの実行関数をそれぞれ変更します.このセグメントコードはコアコードです.よく読んでください.
// the first thread function
void *thread_func1(void *param)
{
int i = 0;
int res = 0;
pthread_t thread_id;
thread_id = pthread_self();
printf("Thread ID::%u -----------S----------
",(unsigned int)thread_id);
while(i++ < 4)
{
#if MUTEX_ENABLE
res = pthread_mutex_lock(&mutex_value1); // mutex1 is locking
if(res != 0)
{
printf(" mutex1 lock failed
");
}
#endif
read_data("Thread_1");
#if MUTEX_ENABLE
res = pthread_mutex_lock(&mutex_value2); //mutex2 is locking
if(res != 0)
{
printf(" mutex2 lock failed
");
}
#endif
#if MUTEX_ENABLE
res = pthread_mutex_unlock(&mutex_value2);
if(res != 0)
{
printf(" mutex2 unlock failed
");
}
res = pthread_mutex_unlock(&mutex_value1);
if(res != 0)
{
printf(" mutex1 unlock failed
");
}
#endif
sleep(2);
}
printf("Thread ID::%u -----------E----------
",(unsigned int)thread_id);
pthread_exit(&status); // end the thread
}
// the second thread function
void *thread_func2(void *param)
{
int i = 0;
int res = 0;
pthread_t thread_id;
thread_id = pthread_self();
printf("Thread ID::%u -----------S----------
",(unsigned int)thread_id);
while(i++ < 4)
{
#if MUTEX_ENABLE
res = pthread_mutex_lock(&mutex_value2); //mutex 2 is locking
if(res != 0)
{
printf(" mutex2 lock failed
");
}
#endif
write_data("Thread_2");
#if MUTEX_ENABLE
res = pthread_mutex_lock(&mutex_value1); //mutex 1 is locking
if(res != 0)
{
printf(" mutex1 lock failed
");
}
#endif
#if MUTEX_ENABLE
res = pthread_mutex_unlock(&mutex_value1);
if(res != 0)
{
printf(" mutex1 unlock failed
");
}
#endif
#if MUTEX_ENABLE
res = pthread_mutex_unlock(&mutex_value2);
if(res != 0)
{
printf(" mutex2 unlock failed
");
}
#endif
sleep(1);
}
printf("Thread ID::%u -----------E----------
",(unsigned int)thread_id);
pthread_exit(&status); // end the thread
}
上記のプログラムを実行すると、次の結果が得られます.
Create first thread //
Create second thread //
Thread ID::3076344640 -----------S----------
[Thread_1] start reading data // ,
Thread ID::3067951936 -----------S----------
[Thread_2] start writing data // ,
[Thread_1] data = 0
[Thread_1] end reading data // ,
[Thread_2] data = 1
[Thread_2] end writing data // ,
mutex2 can't be destroyed // ,
上記のプログラムの実行結果から、スレッド1は反発量1をロックし、反発量2を待つことがわかる.スレッド2は、反発量2をロックし、反発量1を待つ.これによりデッドロックが発生し、プログラムの実行エラーが発生します.
このプログラムはデッドロックの原因を示すために書かれています.このようにプログラムを書くのは合理的ではありません.スレッドを同期できないので、プログラムの内容にこだわらないで、デッドロックがどのように発生したのかを理解することに重点を置いています.
官达を见て、本文の中でコードを书かないで、完成したコードは私の资源の中に置いて、みんなはここをクリックしてダウンロードして使うことができます.
皆さん、スレッドのデッドロックの例についてお話しします.後に何か例があるか知りたいので、次の分解を聞いてください.