いっしょにtalk C栗(第百一十六回:C言語例--スレッド同期の反発量二)


皆さん、こんにちは、前回はスレッド同期の信号量の例を話しましたが、今回はこの例を続けてみましょう.余談はさておき,話は本筋に戻る.一緒にtalk C栗を食べましょう!
反発量相関関数の使い方を前回で詳しく紹介したが,今回はこれらの関数を用いて反発量を操作する方法を紹介した.
詳細な手順は、次のとおりです.
  • 1.スレッドを同期するための反発量Aを定義します.
  • 2.スレッドを作成するプロセスでpthread_を使用するmutex_Init関数は反発量を初期化し、反発量の属性はデフォルト値を使用します.
  • 3.データを読み込むスレッドでデータを読み込むには、まずpthread_を使用します.mutex_lock関数は反発量Aをロック操作する.次にデータを読み込み、pthread_を使用します.mutex_unlock関数は反発量Aをロック解除操作する.
  • 4.書き込みデータのスレッドでデータを変更するには、まずpthread_を使用します.mutex_lock関数は反発量Aをロック操作する.次にデータを変更し、pthread_を使用します.mutex_unlock関数は反発量Aをロック解除操作する.
  • 5.スレッドを作成するプロセスでpthread_を使用するmutex_destroy関数は反発量に関連するリソースを解放する.

  • 官達を見て、本文の中でコードを書かないで、詳しいコードは私の資源の中に置いて、みんなはここをクリックしてダウンロードして使うことができます.
    私たちが書いたコードは信号量反発コードに基づいて修正されたが,信号量の代わりにコードに反発量を用いた.コードに読み書きされたデータの関数は,問題の説明を容易にするために独自に実現され,この2つの関数ではいずれも遅延操作が用いられ,読み書きに一定の時間がかかることを説明するためである.
    プログラムの実行中に次のような状況が発生する可能性があります.
  • 読み取り操作がまだ完了していないので、書き込み操作を開始します.これにより、読み取り操作で読み取ったデータが正確ではありません.
  • 書き込み操作がまだ完了していないので、読み取り操作を開始します.これにより、読み取り操作で読み取ったデータが正確ではありません.

  • 以下に、反発量を使用していない場合のプログラムの実行結果を示します.参考にしてください.
    Create first thread         //       
    Create second thread        //       
    Thread ID::3076062016 -----------S---------- 
    [Thread_1] start reading data //           (             )
    Thread ID::3067669312 -----------S---------- 
    [Thread_2] start writing data //           
    [Thread_1] data = 0 //                  
    [Thread_1] end reading data 
    [Thread_2] data = 1 //              
    [Thread_2] end writing data 
    [Thread_2] start writing data 
    [Thread_1] start reading data 
    [Thread_2] data = 2 
    [Thread_2] end writing data 
    [Thread_1] data = 2 
    [Thread_1] end reading data 
    [Thread_2] start writing data 
    [Thread_2] data = 3 
    [Thread_2] end writing data 
    [Thread_1] start reading data 
    [Thread_2] start writing data 
    [Thread_1] data = 3 
    [Thread_1] end reading data 
    [Thread_2] data = 4 
    [Thread_2] end writing data 
    Thread ID::3067669312 -----------E---------- //       
    [Thread_1] start reading data 
    [Thread_1] data = 4 
    [Thread_1] end reading data 
    Thread ID::3076062016 -----------E---------- //       

    以上の結果から、2番目のスレッドがまだデータを書き終わっていないうちに、1番目のスレッドがデータの読み取りを開始し、共有データの初期化値が読み込まれていることがわかります.彼が読み取った値は、2番目のスレッドが修正されたデータではなく、正確なデータではないことがわかります.さらに下を見ると、データを読み取るスレッドとデータを修正するスレッドが交互に実行されるため、スレッドの実行順序も正しくありません.このことから,スレッドを同期操作しないと,共有データを操作するとエラーの結果が生じる.
    次に、反発量同期スレッドを使用したプログラムの実行結果を示します.参考にしてください.
    Create first thread                //       
    Create second thread               //       
    Thread ID::3075980096 -----------S---------- 
    [Thread_1] start reading data //           (             )
    Thread ID::3067587392 -----------S---------- 
    [Thread_1] data = 0 //                  
    [Thread_1] end reading data //             
    [Thread_2] start writing data //               
    [Thread_2] data = 1 //              
    [Thread_2] end writing data //             
    [Thread_1] start reading data //               
    [Thread_1] data = 1 //                  
    [Thread_1] end reading data //             
    [Thread_2] start writing data 
    [Thread_2] data = 2 
    [Thread_2] end writing data 
    [Thread_1] start reading data 
    [Thread_1] data = 2 
    [Thread_1] end reading data 
    [Thread_2] start writing data 
    [Thread_2] data = 3 
    [Thread_2] end writing data 
    [Thread_1] start reading data 
    [Thread_1] data = 3 
    [Thread_1] end reading data 
    [Thread_2] start writing data 
    [Thread_2] data = 4 
    [Thread_2] end writing data 
    Thread ID::3075980096 -----------E---------- //       
    Thread ID::3067587392 -----------E---------- //       

    以上の結果から、最初のスレッドはまずデータの読み取りを開始し、データの読み取りが完了した後、2番目のスレッドはデータの修正を開始することがわかります.このとき、1番目のスレッドは待機状態にあり、2番目のスレッドがデータを修正してからデータの読み取りを開始し、正確な共有データが読み込まれます.さらに下を見ると、データを読み取るスレッドと、データを修正するスレッドが順番に実行されます.このことから,スレッドを同期操作すると,共有データに対する操作順序が正しく,共有データから読み出した値も正しい.また,信号量を用いたスレッドの同期動作を比較する.共有データの最初の操作は書き込み操作であり、反発量同期スレッドを使用する場合、共有データの最初の操作は読み取り操作である.通常、データの内容を読むには、データを修正する必要があります.このことから,信号量はスレッドの動作順序に対してより厳格であることが分かる.
    我々の経験から,信号量はカウントや順序に厳格な要求がある場合によく用いられ,反発量は共有リソースへのアクセスによく用いられる.もちろん、スレッドを同期するときは、自分のニーズとプログラムの要求に応じて信号量と反発量を選択することができます.
    皆さん、スレッド同期の反発量の例についてお話しします.後に何か例があるか知りたいので、次の分解を聞いてください.