Linux C-マルチスレッドの同期と反発
3724 ワード
一、反発ロックの定義、初期化、反発操作の実現メカニズム?
1.反発ロックの定義
反発ロックは、2つのプロセスまたはスレッドが同じ時点で同じ共有リソースにアクセスすることを防止するためによく使用される信号量である.本質的には、反発量は、1つまたはいくつかのリソースを保護するロックです.1つのスレッドがリソースにアクセスする必要がある場合は、反発量を取得してロックする必要があります.この場合、他のスレッドがリソースにアクセスするにも反発量を取得する必要がありますが、ロックがロックされているため、ロックを取得したプロセスがロックを解除するまで、これらのプロセスはブロックするしかありません.このとき、ブロックされたスレッドの中には、反発量を取得してロックし、リソースへのアクセスを許可され、他のプロセスがブロックされ続け、繰り返します.
2.反発ロックの初期化
Pthread_mutex_init関数
関数の役割:反発ロックの初期化
関数プロトタイプ:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
パラメータ:mutex:反発ロック
Attr:PTHREAD_MUTEX_INITIALIZERクイック反発ロックの作成
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP再帰的反発ロックの作成
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NPエラーチェック相互反発ロックの作成
戻り値:正常に0を返しました.エラーは-1を返します
3.反発ロック操作の実現メカニズム
次に、スレッド1とスレッド2のそれぞれにヒント情報を印刷し、反発ロックを用いてスレッド1とスレッド2の動作の前後順序を制御する反発ロックの例を示す
二、信号量はスレッド間のPV操作を実現し、スレッド同期と反発のデータモデルを実現する.
1.sem_init関数
関数作用かんすうさよう:初期化信号量しょきかしんごうりょう
関数プロトタイプ:int sem_init(sem_t *sem, int pshared, unsigned int value)
パラメータ:sem:信号量ポインタ
Pshared:信号量がいくつかのプロセス間で共有できるかどうかを決定し、一般的に0をとる
Value:信号量の初期値
2.信号の動作
Int sem_wait(sem_t *sem); P操作
Int sem_try_wait(sem_t *sem);
Int sempost(sem_t *sem); V操作
Int sem_getvalue(sem_t *sem);
Int sem_destroy(sem_t *sem); 破棄信号
3.信号のPV操作で消費者と生産者を実現する仕組み
1.反発ロックの定義
反発ロックは、2つのプロセスまたはスレッドが同じ時点で同じ共有リソースにアクセスすることを防止するためによく使用される信号量である.本質的には、反発量は、1つまたはいくつかのリソースを保護するロックです.1つのスレッドがリソースにアクセスする必要がある場合は、反発量を取得してロックする必要があります.この場合、他のスレッドがリソースにアクセスするにも反発量を取得する必要がありますが、ロックがロックされているため、ロックを取得したプロセスがロックを解除するまで、これらのプロセスはブロックするしかありません.このとき、ブロックされたスレッドの中には、反発量を取得してロックし、リソースへのアクセスを許可され、他のプロセスがブロックされ続け、繰り返します.
2.反発ロックの初期化
Pthread_mutex_init関数
関数の役割:反発ロックの初期化
関数プロトタイプ:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
パラメータ:mutex:反発ロック
Attr:PTHREAD_MUTEX_INITIALIZERクイック反発ロックの作成
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP再帰的反発ロックの作成
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NPエラーチェック相互反発ロックの作成
戻り値:正常に0を返しました.エラーは-1を返します
3.反発ロック操作の実現メカニズム
次に、スレッド1とスレッド2のそれぞれにヒント情報を印刷し、反発ロックを用いてスレッド1とスレッド2の動作の前後順序を制御する反発ロックの例を示す
#include
#include
#include
pthread_mutex_t mutex;
void *thread1(void)
{
int i;
pthread_mutex_lock(&mutex);
for(i = 0; i < 4; i++)
{
printf("this is the 1st pthread
");
sleep(1);
}
pthread_mutex_unlock(&mutex);
}
void *thread2(void)
{
int i;
pthread_mutex_lock(&mutex);
for(i = 0; i < 4; i++)
{
printf("this is the 2nd pthread
");
sleep(1);
}
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t id1,id2;
if(pthread_mutex_init(&mutex,NULL) != 0)
{
printf("init failed!
");
exit(1);
}
if(pthread_create(&id1,NULL,(void *)thread1,NULL) != 0)
{
printf("create thread1 failed!
");
exit(1);
}
if(pthread_create(&id2,NULL,(void *)thread2,NULL) != 0)
{
printf("create thread2 failed!
");
exit(1);
}
pthread_join(id1,NULL);
pthread_join(id2,NULL);
sleep(1);
return 0;
}
二、信号量はスレッド間のPV操作を実現し、スレッド同期と反発のデータモデルを実現する.
1.sem_init関数
関数作用かんすうさよう:初期化信号量しょきかしんごうりょう
関数プロトタイプ:int sem_init(sem_t *sem, int pshared, unsigned int value)
パラメータ:sem:信号量ポインタ
Pshared:信号量がいくつかのプロセス間で共有できるかどうかを決定し、一般的に0をとる
Value:信号量の初期値
2.信号の動作
Int sem_wait(sem_t *sem); P操作
Int sem_try_wait(sem_t *sem);
Int sempost(sem_t *sem); V操作
Int sem_getvalue(sem_t *sem);
Int sem_destroy(sem_t *sem); 破棄信号
3.信号のPV操作で消費者と生産者を実現する仕組み
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX_SIZE 1024
sem_t sem1,sem2;
char buff[MAX_SIZE];
void producer(void *arg)
{
do
{
sem_wait(&sem1);
printf("Producer enter some data:");
scanf("%s",buff);
sem_post(&sem2);
}while(strncmp(buff,"quit",4) != 0);
}
void customer(void *arg)
{
do
{
sem_wait(&sem2);
printf("Customer read is:%s
",buff);
sem_post(&sem1);
}while(strncmp(buff,"quit",4) != 0);
}
int main()
{
pthread_t id1,id2;
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
if(pthread_create(&id1,NULL,(void *)producer,NULL) != 0)
{
printf("init producer error!
");
return -1;
}
if(pthread_create(&id2,NULL,(void *)customer,NULL) != 0)
{
printf("init customer error!
");
return -1;
}
pthread_join(id1,NULL);
pthread_join(id2,NULL);
return 0;
}