マルチスレッドのデッドロックとロック競合の例

2358 ワード

マルチスレッドプログラミングでは、同期を維持するために、反発ロックを使用して臨界領域を保護する必要がありますが、マルチスレッドが反発ロックを共同で使用すると、デッドロックまたはロック競合が発生します.
デッドロック:
デッドロックの原因は主に,(1)システムリソースが不足しているため,(2)プロセスの実行が進む順序が不適切である.(3)資源配分が適切でないなど.システム資源が十分であれば、プロセスの資源要求が満たされ、デッドロックが発生する可能性が低い.そうでなければ、限られた資源を争うことによってデッドロックに陥る.次に、プロセスの運行推進順序と速度が異なり、デッドロックが発生する可能性もある.デッドロックを発生する4つの必要条件:(1)反発条件:1つのリソースは1つのプロセスでしか使用できない.(2)要求と保持条件:1つのプロセスがリソースを要求することによってブロックされた場合、取得したリソースに対して放さない.(3)条件を奪わない:プロセスが取得したリソースは、最後の使用が完了するまで強制的に剥奪することはできない.(4)循環待ち条件:いくつかのプロセスの間に一つの頭と尾がつながっている循環待ち資源関係を形成する.この四つの条件はデッドロックの必要条件であり、システムにデッドロックが発生すれば、これらの条件は必ず成立し、上記の条件の一つが満たさなければ、デッドロックは発生しない.デッドロックの解除と予防:デッドロックの原因を理解し、特にデッドロックが発生した四つの必要な条件は、デッドロックを最大限に回避、予防、解除することができる.だから、システム設計、プロセススケジューリングなどの面でどのようにこの4つの必要条件を成立させないかに注意し、どのように資源の合理的な分配アルゴリズムを確定し、プロセスが永久にシステム資源を占有することを避けるか.また、プロセスが待機状態でリソースを占有することを防止します.そのため、資源の分配に対して合理的な計画を与えなければならない.
ロック競合:
ロックされたスレッドは同じ反発ロックを使用し、別のスレッドはまず本スレッドとロックされ、本スレッドはロックされたときにブロックするしかありません.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
pthread_mutex_t mutex;
void print(char* buf)
{
	int i;
	pthread_mutex_lock(&mutex);
	for(i=0;i<strlen(buf);i++)
	{
		printf("I am in print buf[%d] is %c\r
",i,buf[i]); } pthread_mutex_unlock(&mutex); } void *thread1(void* arg) { char *buf; int i; pthread_mutex_lock(&mutex); buf = (char*)arg; printf("before in thread1\r
"); sleep(1); // print(buf); for(i=0;i<strlen(buf);i++) { printf("I am from thread1 buf[%d] is %c\r
",i,buf[i]); usleep(100); } pthread_mutex_unlock(&mutex); return NULL; } void *thread2(void* arg) { char *buf; int i; printf("before in thread 2\r
"); pthread_mutex_lock(&mutex); buf = (char*)arg; sleep(1); for(i=0;i<strlen(buf);i++) { printf("I am from thread2 buf[%d] is %c\r
",i,buf[i]); usleep(100); } pthread_mutex_unlock(&mutex); return NULL; } int main() { pthread_t pid1,pid2; char buf[]="abcdefg"; pthread_create(&pid1,NULL,thread1,(void*)buf); usleep(100); pthread_create(&pid2,NULL,thread2,(void*)buf); pthread_join(pid1,NULL); pthread_join(pid2,NULL); return 0; }
上の例はロック競合の場合、printの行の注釈を削除し、スレッドを1つ開くだけでデッドロック現象をもたらします.
ロック競合によりスレッドがブロックされますが、デッドロックによりスレッドが動作しません.