POSIX 스 레 드 (pthread) (2)
8523 단어 pthread
스 레 드 동기 화
pthread 는 세 가지 동기 화 메커니즘 을 제공 합 니 다.
서로 배척 하 는 것 은 여러 스 레 드 가 같은 빠 른 메모리 구역 에 접근 하여 데이터 가 일치 하지 않 거나 일부 작업 이 하나의 메모리 가 필요 해서 경쟁 이 생기 는 것 을 방지 하 는 데 자주 사용 된다.경쟁 은 항상 2 개 또는 여러 개의 스 레 드 가 같은 빠 른 메모 리 를 조작 할 때 발생 하지만 결 과 는 호출 된 우선 순위 에 따라 계산 하 기 를 원한 다.공 유 된 메모리 에 순서대로 접근 할 수 있 도록 서로 배척 하 다.모든 자원 이 여러 스 레 드 에 접근 할 때 자 물 쇠 를 추가 해 야 합 니 다. 자 물 쇠 는 자원 이 다른 스 레 드 에 접근 하지 않도록 보호 할 수 있 습 니 다.자 물 쇠 는 스 레 드 에 만 사용 할 수 있 습 니 다. 그렇지 않 으 면 신 호 량 이 작용 하지 않 습 니 다.
예:
Without Mutex
With Mutex
int counter=0;
/* Function C */
void functionC()
{
counter++
}
/* Note scope of variable and mutex are the same */
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter=0;
/* Function C */
void functionC()
{
pthread_mutex_lock( &mutex1 );
counter++
pthread_mutex_unlock( &mutex1 );
}
Possible execution sequence
Thread 1
Thread 2
Thread 1
Thread 2
counter = 0
counter = 0
counter = 0
counter = 0
counter = 1
counter = 1
counter = 1
Thread 2 locked out. Thread 1 has exclusive use of variable counter
counter = 2
첫 번 째 는 서로 배척 하지 않 는 경우 레지스터 가 이 증가 하 는 변수 conter 를 읽 고 저장 하 는 시기 가 좋 지 않 으 면 첫 번 째 스 레 드 가 기록 한 값 이 두 번 째 스 레 드 가 기록 한 값 으로 덮어 쓸 수도 있 고 두 번 째 스 레 드 가 먼저 값 을 기록 하여 첫 번 째 스 레 드 에 덮어 쓸 수도 있 습 니 다.두 번 째 는 스 레 드 가 증가 변수 conter 에 접근 하면 이 값 을 잠 그 고 실행 이 끝 날 때 까지 잠 금 을 풀 어 다른 스 레 드 에 접근 하도록 하 는 것 입 니 다.
Sequence
Thread 1
Thread 2
1
counter = 0
counter=0
2
Thread 1 locked out. Thread 2 has exclusive use of variable counter
counter = 1
3
counter = 2
예 mtex 1. c:
#include
#include
#include
void *functionC();
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
main()
{
int rc1, rc2;
pthread_t thread1, thread2;
/* Create independent threads each of which will execute functionC */
if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
{
printf("Thread creation failed: %d
", rc1);
}
if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) )
{
printf("Thread creation failed: %d
", rc2);
}
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
exit(EXIT_SUCCESS);
}
void *functionC()
{
pthread_mutex_lock( &mutex1 );
counter++;
printf("Counter value: %d
",counter);
pthread_mutex_unlock( &mutex1 );
}
컴 파일:cc - pthread mutex1. c (or cc - lpthread mutex1. c 오래된 버 전의 GNU 컴 파일 러)
실행:. / a. out Results: Counter value: 1 Counter value: 2
스 레 드 가 잠 겨 있 는 변 수 를 방문 하려 고 시도 할 때 이 스 레 드 는 막 힐 것 입 니 다.하나의 스 레 드 가 끝 날 때, 상호 배척 자 물 쇠 는 자동 으로 풀 리 지 않 는 다.
연결 하 다
연결 의 역할 은 다른 스 레 드 가 실 행 된 후에 실 행 될 때 까지 기다 리 는 것 입 니 다. 한 스 레 드 의 호출 은 몇 개의 스 레 드 가 실 행 된 후의 결 과 를 필요 로 합 니 다. 이 럴 때 연결 이 필요 합 니 다.
예 join 1. c:
#include
#include
#define NTHREADS 10
void *thread_function(void *);
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
main()
{
pthread_t thread_id[NTHREADS];
int i, j;
for(i=0; i < NTHREADS; i++)
{
pthread_create( &thread_id[i], NULL, thread_function, NULL );
}
for(j=0; j < NTHREADS; j++)
{
pthread_join( thread_id[j], NULL);
}
/* Now that all threads are complete I can print the final result. */
/* Without the join I could be printing a value before all the threads */
/* have been completed. */
printf("Final counter value: %d
", counter);
}
void *thread_function(void *dummyPtr)
{
printf("Thread number %ld
", pthread_self());
pthread_mutex_lock( &mutex1 );
counter++;
pthread_mutex_unlock( &mutex1 );
}
컴 파일: cc - pthread join1. c (또는 cc - lpthread join1. c 오래된 GNU 컴 파일) 실행:. / a. out 결과: Thread number 1026 Thread number 2051 Thread number 3076 Thread number 4101 Thread number 5126 Thread number 6151 Thread number 7101 Thread number 8201 Thread number 9226 Thread number 10251 최종 카운터 값: 10
조건 변수
조건 변수의 유형 은 pthreadcond_t, 함수 호출 시 지연 처리 에 사용 합 니 다.이 조건 변수의 메커니즘 은 라인 이 끊 어 지 는 것 을 허용 하지만 조건 이 만족 할 때 계속 실행 하 는 것 이다.조건 변 수 는 반드시 상호 배척 변수 와 함께 사용 해 야 합 니 다. 이렇게 하면 피 할 수 있 습 니 다. 한 스 레 드 는 다른 스 레 드 를 기다 리 고 있 습 니 다. 다른 스 레 드 는 조건 도 첫 번 째 스 레 드 가 신 호 를 촉발 하 기 를 기다 리 고 있 습 니 다. 그러면 두 스 레 드 는 서로 실행 되 기 를 영원히 기다 리 고 있 기 때문에 잠 금 을 초래 합 니 다.조건 변수 와 상호 배척 자물쇠 사이 에는 현저 한 차이 가 없고 두 개 는 프로그램 에서 모두 사용 할 수 있다.
조건 변수 에 대한 설명:
창설 및 폐기
pthread_cond_init
pthread_cond_t cond =PTHREAD_COND_INITIALIZER
pthread_cond_destory
기다리다
pthread_cond_wait 잠 금 해제 및 대기 조건 이 실 행 됩 니 다.
pthread_cond_timewait 설정 대기 시간 초과
깨어나다
pthread_cond_signal 은 이 조건 변 수 를 기다 리 는 스 레 드 를 계속 실행 합 니 다.
pthread_cond_broadcast 이 조건 변수 로 인해 막 힌 모든 스 레 드 가 계속 실 행 됩 니 다.
예:
#include
#include
#include
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
void *functionCount1();
void *functionCount2();
int count = 0;
#define COUNT_DONE 10
#define COUNT_HALT1 3
#define COUNT_HALT2 6
main()
{
pthread_t thread1, thread2;
pthread_create( &thread1, NULL, &functionCount1, NULL);
pthread_create( &thread2, NULL, &functionCount2, NULL);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("Final count: %d
",count);
exit(EXIT_SUCCESS);
}
// Write numbers 1-3 and 8-10 as permitted by functionCount2()
void *functionCount1()
{
for(;;)
{
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
// Wait while functionCount2() operates on count
// mutex unlocked if condition varialbe in functionCount2() signaled.
pthread_cond_wait( &condition_var, &count_mutex );
count++;
printf("Counter value functionCount1: %d
",count);
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
// Write numbers 4-7
void *functionCount2()
{
for(;;)
{
pthread_mutex_lock( &count_mutex );
if( count < COUNT_HALT1 || count > COUNT_HALT2 )
{
// Condition of if statement has been met.
// Signal to free waiting thread by freeing the mutex.
// Note: functionCount1() is now permitted to modify "count".
pthread_cond_signal( &condition_var );
}
else
{
count++;
printf("Counter value functionCount2: %d
",count);
}
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
컴 파일: cc - pthread cond1. c (or cc - lpthread cond1. c 오래된 버 전의 GNU 컴 파일 러) 실행:. / a. out
결과:
Counter value functionCount1: 1
Counter value functionCount1: 2
Counter value functionCount1: 3
Counter value functionCount2: 4
Counter value functionCount2: 5
Counter value functionCount2: 6
Counter value functionCount2: 7
Counter value functionCount1: 8
Counter value functionCount1: 9
Counter value functionCount1: 10
Final count: 10
주의: 하지만 count 의 값 은 COUNTHALT 1 과 COUNTHALT 2 사이 에 function 1 () 이 실행 을 멈 추 었 습 니 다.유일 하 게 확실한 것 은 count 의 값 은 COUNTHALT 1 과 COUNTHALT 2 간 function 2 () 는 count 의 값 을 증가 시 키 고 다른 경 우 는 무 작위 입 니 다.
논리 적 조건 if 와 while 는 기다 릴 때 '신호' 가 실 행 될 수 있 도록 합 니 다.나 쁜 논 리 는 자 물 쇠 를 일 으 킬 수 있다.
주의: 이 예 에서 의 경쟁 조건 은 count 입 니 다. 그 는 while 순환 종 에 잠 겨 있 으 면 안 됩 니 다. 그렇지 않 으 면 잠 겨 있 습 니 다.