Linuxオペレーティングシステムマルチスレッド同期反発Mutexの使用


1.初期化
Linuxではスレッドの反発量データ型はpthread_mutex_t.使用前に初期化するには、次の手順に従います.
静的割当ての反発量については、PTHREAD_に設定できます.MUTEX_INITIALIZER、またはpthread_を呼び出すmutex_init.
動的に割り当てられた反発量については、メモリ(malloc)を申請した後、pthread_を介してmutex_Initは初期化され、メモリを解放する前にpthread_を呼び出す必要があります.mutex_destroy.
ヘッダファイル:#include
プロトタイプ:
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restric attr);

int pthread_mutex_destroy(pthread_mutex_t *mutex); 

戻り値:成功すると0、エラーが発生するとエラー番号が返されます.
説明:デフォルトのプロパティを使用して反発量を初期化する場合は、attrをNULLに設定するだけです.その他の値は後で説明します.
2.反発操作
共有リソースへのアクセスは、反発量をロックし、反発量がロックされている場合、呼び出しスレッドは反発量がロック解除されるまでブロックする.共有リソースへのアクセスが完了したら、反発量をロック解除します.
まず、ロック関数について説明します.
ヘッダファイル:#include
プロトタイプ:
int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex); 

戻り値:成功すると0、エラーが発生するとエラー番号が返されます.
説明:具体的にはtrylock関数を説明します.この関数は非ブロック呼び出しモードです.つまり、反発量がロックされていない場合、trylock関数は反発量をロックし、共有リソースへのアクセス権を取得します.反発量がロックされている場合、trylock関数は待機をブロックせずにEBUSYに戻り、共有リソースが忙しいことを示します.
 
ロック解除関数をもう一度言います.
ヘッダファイル:#include
プロトタイプ:
int pthread_mutex_unlock(pthread_mutex_t *mutex); 

戻り値:成功すると0、エラーが発生するとエラー番号が返されます.
3.デッドロック
デッドロックは、主に複数の依存ロックが存在する場合に発生し、あるスレッドが別のスレッドとは逆の順序で反発量をロックしようとする場合に発生します.デッドロックを回避するには,反発量を用いて特に注意すべきものである.
全体的に言えば、いくつかの不文の基本原則があります.
共有リソースを操作する前にロックを取得する必要があります.
操作が完了したら、必ずロックを解除してください.
ロックをできるだけ短時間で占有する.
複数のロックがある場合、取得順序がABCボタンであれば、解放順序もABCであるべきである.
スレッドエラーが返されると、取得したロックが解放されます.
4.コードサンプル
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;// 
int lock_var;// 
time_t end_time;

void pthread1(void *arg);// 1
void pthread2(void *arg);// 2

int main(int argc, char *argv[])
{
	pthread_t id1,id2;
	pthread_t mon_th_id;
	int ret;

	end_time = time(NULL)+10;
	pthread_mutex_init(&mutex,NULL);// mutex , ( NULL)
	ret=pthread_create(&id1,NULL,(void *)pthread1, NULL);// 1
	if(ret!=0)
		perror("pthread cread1");

	ret=pthread_create(&id2,NULL,(void *)pthread2, NULL);// 2
	if(ret!=0)
		perror("pthread cread2");

	pthread_join(id1,NULL);// 1 
	pthread_join(id2,NULL);// 2 

	exit(0);
}

void pthread1(void *arg)
{
	int i;
	while(time(NULL) < end_time)
	{
		if(pthread_mutex_lock(&mutex)!=0) // 
		{
			perror("pthread_mutex_lock");
		}else{
			printf("pthread1:pthread1 lock the variable
"); } for(i=0;i<2;i++) { sleep(2); lock_var++; } if(pthread_mutex_unlock(&mutex)!=0) // { perror("pthread_mutex_unlock"); }else{ printf("pthread1:pthread1 unlock the variable
"); } sleep(1); } } void pthread2(void *arg) { int nolock=0; int ret; while(time(NULL) < end_time){ ret=pthread_mutex_trylock(&mutex);// if(ret==EBUSY){ printf("pthread2:the variable is locked by pthread1
"); }else{ if(ret!=0){ perror("pthread_mutex_trylock"); exit(1); }else{ printf("pthread2:pthread2 got lock.The variable is %d
",lock_var); } if(pthread_mutex_unlock(&mutex)!=0){// perror("pthread_mutex_unlock"); }else{ printf("pthread2:pthread2 unlock the variable
"); } } sleep(1); } }

注意:pthreadライブラリはLinuxシステムのデフォルトのライブラリではないため、接続時に静的ライブラリlibpthreadを使用する必要があります.a、だからpthread_を使ってcreate()スレッドなどの他のスレッド操作を作成する場合は、ライブラリにリンクする必要があります.すなわち、コンパイルに-lpthreadパラメータを追加します.
実行結果:
pthread2:pthread2 got lock.The variable is 0
pthread2:pthread2 unlock the variable
pthread1:pthread1 lock the variable
pthread2:the variable is locked by pthread1
pthread2:the variable is locked by pthread1
pthread2:the variable is locked by pthread1
pthread1:pthread1 unlock the variable
pthread2:pthread2 got lock.The variable is 2
pthread2:pthread2 unlock the variable
pthread1:pthread1 lock the variable
pthread2:the variable is locked by pthread1
pthread2:the variable is locked by pthread1
pthread2:the variable is locked by pthread1
pthread2:the variable is locked by pthread1
pthread1:pthread1 unlock the variable
pthread2:pthread2 got lock.The variable is 4
pthread2:pthread2 unlock the variable

原文住所:
Linuxオペレーティングシステムマルチスレッド同期Mutexの詳細