Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> セマフォを使ってLinuxのスレッド同期を制御する

セマフォを使ってLinuxのスレッド同期を制御する

  

スレッド同期実際には、いくつかのことを順番に実行しなければなりません。終了した後でなければ、作業結果を続けることはできません。あなたは働き始めています。これはスレッド同期の最もわかりやすい説明です。

プログラミングでも同じことが言えます。スレッド同期、同期とは何ですか?共有リソース(メモリ領域、パブリック変数など)または重要な領域へのアクセスを同期します。時々、これらの共有リソースとクリティカル領域はスレッドがそれを操作することしか許容できない(読み込みまたは書き込み、読み込み操作は一般に制御されない、主に書き込み操作)、現時点では、これらのリソースを共有する必要があります。リージョンは同期されています、それではどのようにそれらをスレッドと同期させますか?

Linuxでは、主に次の2つの方法が提供されています。

セマフォとの同期mutexとの同期どの方法を使用しても、スレッド同期のためのものです。セマフォのスレッド同期の詳細な要約。

セマフォの概念を理解するための最初のセマフォとは何ですか。セマフォは増減できる特別な種類の変数ですが、マルチスレッドプログラムであっても、セマフォへのアクセスはアトミック操作であることが保証されています。つまり、プログラム内の2つ以上のスレッドがセマフォの値を変更しようとすると、システムはすべての操作が順番に実行されるようにします。通常の変数に切り替えると、同じプログラム内の異なるスレッドからの競合する操作は、不確定な操作になります。

あなたの作品には、バイナリセマフォとカウントセマフォという2種類のセマフォがあります。バイナリセマフォには0と1の2つの値しかありませんが、カウントセマフォにはより広い範囲の値があります。共有リソースが1つのスレッドからしかアクセスできない場合は、バイナリセマフォが最善のアイデアです;共有リソースにアクセスする必要があるスレッドが複数ある場合は、カウントセマフォを使用することをお勧めします。

セマフォ関連APIは、セマフォを実装するためにLinuxでいくつかの関連APIインタフェースを提供しています最初にこれらのインタフェースと混在させ、次にこれらのインタフェースの使用方法をよく理解するために小さな例を使用します。

/***セマフォの作成* @param setm_t * semセマフォオブジェクト、オブジェクトの完全な初期化* @param int psharedセマフォの型;値が0の場合、このセマフォを意味します。現在のプロセスのローカルセマフォです;そうでなければ、このセマフォは複数のプロセス間で共有できます* @param unsigned int valueセマフォの初期値* @return intは成功すると0を返し、失敗すると-1 * /intを返します。 sem_initは(sem_t * SEM、INTのpshared、unsigned int型の値); /***信号の値マイナス1 * @param sem_t *セマフォオブジェクト得sem_init * @returnのINTコールリターン0成功した場合のアトミック量; -1を返すことができませんでした* /int sem_wait(sem_t * sem); /***アトミック操作1によってセマフォの値を追加します1 * @param sem_t * sem_initを呼び出すことによって得られたセマフォオブジェクト* @return int 0を返します。-1を返します* /int型sem_post(sem_t * SEM)失敗; /*** @param sem_t * SEMコールが得られsem_init *セマフォのセマフォオブジェクトのカウント値* @param int型&値は、実際に返さセマフォの値* @return intは成功すると0を返し、失敗すると-1 * /intを返します。 sem_getvalue(sem_t * SEM、INT&値); /***所有セマフォのすべてのリソースをクリーンアップ;信号の量待機され、いくつかのスレッドをクリーンアップしようとすると、エラーが表示されます* @param sem_t * sem_initを呼び出しますセマフォオブジェクトは、* @return INT成功戻り0;返す-1 * /INT sem_destroy(sem_t * SEM)障害;セマフォのsem_wait値がデクリメントされるであろうが、セマフォ値以上であるまで、待機します1時に、1を減分する動作が開始される。したがって、2のコールsem_waitセマフォ値場合、スレッドは実行を継続し、sem_wait操作信号が0である場合、他のスレッドは、セマフォ値がありませんのでインクリメントされるまで、この関数は待機する一方また0です。

セマフォ操作用のAPI関数の小さなインスタンスが導入されました。実際のコーディングを通じて、これらの関数を使用するための小さなプログラムを使用するようになりました。

次のステップは、そのような関数を完成させることです:

メインスレッドは標準入力端末から入力を読み、子スレッド1はメインスレッドからの入力を大文字に変換します。それでは、上記の関数に従ってコードを実装しましょう。シンプルなので、私は達成するつもりです特徴:メインスレッドの初期化セマフォで

が0であり、メインスレッドが入力されると、セマフォの値を大きくsem_post呼び出し、子スレッド1に、セマフォまで待って、sem_waitを呼び出します値1は、セマフォの値を減らしてから、スレッド内のコードを実行します。わかりました、それをコーディングします。

の#include< stdio.hの>の#include< unistd.h>の#include< STDLIB.H>の#include< pthread.hの>の#include< semaphore.h>ボイド* threadFunc( void *型のarg); sem_t SEM;の#define WORK_SIZE 1024char work_area [WORK_SIZE];アクセス共有リソースへの//メインスレッドと子スレッド(メインint型){int型のres;がpthread_t upperThread; void *型threadRes; RES = sem_init(&#038; SEM 、0、0); {;)にperror(]である。セマフォ初期化失敗"出口(EXIT_FAILURE);} //!セマフォが0

IF(RES = 0)に初期化さ

RES =のpthread_create(&#038; upperThread、NULL、threadFunc、NULL); IF(!RES = 0){perrorは("スレッドの作成が;.失敗");出口(EXIT_FAILURE);}のprintf("入力テキストを変換してください、ついで)\\ N]である。終了する '末端' と入力し、一方(strncmpは(" END"、work_area、3)= 0){関数fgets(work_area、WORK_SIZE、STDIN);! sem_post(&#038; SEM); //RES = sem_getvalue(アンペア&; SEM、&#038; semValue);入力が完了すると、セマフォint型semValue = 0の値を大きく//セマフォの現在値のprintfを取得("セマフォカウント:%D \\ N"、semValue)。

のprintf(" \\ nWaiting終了するスレッドのために... \\ N"); RES = pthread_joinを(upperThread、&#038; threadRes);(もし!RES = 0){perrorは("参加が失敗]である。スレッド);出口(EXIT_FAILURE);}のprintf("スレッドが\\に参加し、N]である。); sem_destroy(&#038; SEM)、出口(EXIT_SUCCESS);}ボイド* threadFunc(ボイド*引数){sem_wait(&#038; SEM); //

一方(strncmpは("エンド":sem_getvalue(&#038; SEM、&#038; semValue);のprintf(;%D \\ N" semValue"セマフォカウント)セマフォINT semValue = 0の値を減少させます;、work_area、3)!= 0){for(int i = 0; work_area [i]!= '\\ 0'; ++ i){if(work_area [i]> = 'a'&& A work_area [I] |≦ 'Z'){work_area [I] = work_area [I] - 32;}}

のprintf("後convtered:%S \\ N"、work_area); sem_wait( & sem); //入力を待って、再びブロックします} pthread_exit(NULL);}zh-CN"],null,[1],zh-TW"]]]

Copyright © Windowsの知識 All Rights Reserved