Linux 다 중 스 레 드 프로 그래 밍 상세 설명 - 조건 변수 pthreadcond_t
http://blog.csdn.net/ithomer/article/details/6031723
http://blog.sina.com.cn/s/blog_825085b601018xfp.html
http://blog.csdn.net/ffilman/article/details/4871920
다 중 스 레 드 프로 그래 밍 에서 A 스 레 드 는 B 스 레 드 조건 이 완 료 된 후에 계속 진행 해 야 합 니 다. 여기 서 기다 리 는 방식 은 두 가지 가 있 습 니 다.
1. 자물쇠 + 폴 링 사용
이런 방법 을 사용 하면 쉽게 실현 할 수 있 지만 일정한 성능 소모 가 있 을 것 이다. 그 중 하 나 는 바로 한 번 의 문의 가 결과 가 없 으 면 얼마 만 에 다음 번 의 문의 가 진행 되 고 간격 이 너무 짧 으 며 소모 하 는 CPU 자원 이 비교적 많 고 간격 이 너무 길 어서 신속하게 요청 에 응 하지 못 하 는 것 이다.
그래서 이런 방법 은 추천 이 아 닙 니 다.
2. 조건 변수의 스 레 드 동기 화 사용 (추천)
차단 과 정보 방식 을 채택 하면 자원 의 낭 비 를 크게 줄 이 고 실시 간성 을 증가 시 킬 수 있다
스 레 드 조건 변수 pthreadcond_t
스 레 드 대기 조건
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
알림 함수
모든 스 레 드 알림
int pthread_cond_broadcast(pthread_cond_t *cond);
스 레 드 하나만 알려 주기
int pthread_cond_signal(pthread_cond_t *cond);
---------------------------------------------------------------------------------
올 바른 사용법
pthread_cond_wait 사용법:
pthread_mutex_lock(&mutex);
while(condition_is_false)
{
pthread_cond_wait(&cond,&mutex);
}
condition_is_false=true; //이 조작 은 자물쇠 가 달 린 것 이다. 즉, 하나의 스 레 드 만 이 동시에 이곳 에 들 어 온 다 는 것 이다.
pthread_mutex_unlock(&mutex);
----------------------------------------------------
pthread cond signal 용법:
pthread_mutex_lock(&mutex);
condition_is_false=false;
pthread_cond_signal(&cond)
pthread_mutex_unlock(&mutex)
--------------------------------------------------------
위의 용법 을 기억 하 세 요!! pthread cond broadcast 를 잘못 사용 하지 않도록 모든 조건 변 수 를 방출 할 수 있 습 니 다.
다음은 pthread cond XX 의 용법 입 니 다.
1. 조건 변수 pthread cond init 초기 화
#include
int pthread_cond_init(pthread_cond_t *cv,
const pthread_condattr_t *cattr);
반환 값: 함수 가 0 을 성공 적 으로 되 돌려 주 었 습 니 다. 다른 반환 값 은 모두 오 류 를 표시 합 니 다.
조건 변 수 를 초기 화 합 니 다. 매개 변수 cattr 가 빈 포인터 일 때 함 수 는 결 성 된 조건 변 수 를 만 듭 니 다. 그렇지 않 으 면 조건 변수의 속성 은 cattr 의 속성 값 에 의 해 결 정 됩 니 다. pthread cond init 함 수 를 호출 할 때 매개 변수 cattr 는 빈 포인터 로 cattr 의 속성 은 결 성 속성 입 니 다. 전 자 는 cattr 가 사용 하 는 메모리 비용 이 필요 하지 않 습 니 다. 이 함 수 는 cattr 가 사용 하 는 메모리 비용 을 되 돌려 줍 니 다.조건 변 수 는 매개 변수 cv 가 가리 키 는 메모리 에 저 장 됩 니 다.
매크로 PTHREAD COND INITIALIZER 를 사용 하여 정적 으로 정 의 된 조건 변 수 를 초기 화 할 수 있 습 니 다. 속성 이 부족 합 니 다. 이것 은 pthread cond init 함수 로 동적 으로 분 배 된 효과 와 같 습 니 다. 초기 화 할 때 오류 검 사 를 하지 않 습 니 다. 예 를 들 어:
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
여러 스 레 드 에서 조건 변 수 를 동시에 초기 화 할 수 없습니다. 조건 변 수 를 다시 초기 화하 거나 풀 어야 할 때 프로그램 은 이 조건 변 수 를 사용 하지 않도록 해 야 합 니 다.
2. 조건 변수 에 pthread cond wait 차단
#include
int pthread_cond_wait(pthread_cond_t *cv,
pthread_mutex_t *mutex);
반환 값: 함수 가 0 을 성공 적 으로 되 돌려 주 었 습 니 다. 다른 반환 값 은 모두 오 류 를 표시 합 니 다.
함 수 는 mutex 매개 변수 가 가리 키 는 상호 배척 자 물 쇠 를 풀 고 현재 스 레 드 를 cv 매개 변수 가 가리 키 는 조건 변수 에 막 습 니 다.
막 힌 스 레 드 는 pthread cond signal 함수, pthread cond broadcast 함수 에 의 해 깨 어 날 수도 있 고 신호 가 끊 긴 후에 깨 어 날 수도 있 습 니 다.
pthread cond wait 함수 의 반환 은 조건 의 값 이 반드시 변 한 것 을 의미 하지 않 으 며 조건 의 값 을 다시 검사 해 야 합 니 다.
pthread cond wait 함수 가 돌아 올 때 해당 하 는 상호 배척 자 물 쇠 는 현재 스 레 드 에 의 해 잠 겨 있 습 니 다. 함수 가 잘못 되 었 더 라 도 돌아 갑 니 다.
일반적인 조건 표현 식 은 상호 배척 잠 금 보호 하에 서 검 사 됩 니 다. 조건 표현 식 이 만족 하지 않 을 때 스 레 드 는 이 조건 변수 에 저 장 됩 니 다. 다른 스 레 드 가 조건 값 을 바 꾸 고 조건 변수 에 신 호 를 보 낼 때 이 조건 변수 에 있 는 스 레 드 나 모든 스 레 드 가 깨 어 날 때 까지 기다 리 고 있 습 니 다. 이 어 해당 하 는 상호 배척 을 다시 차지 하려 고 합 니 다.자물쇠
조건 변수 에 막 힌 스 레 드 가 깨 어 날 때 까지 pthread cond wait ()함수 가 이전 조건 의 값 을 되 돌려 줄 수 있 습 니 다. 따라서 함수 가 돌아 온 후, 해당 하 는 상호 배척 자 물 쇠 를 잠 그 기 전에 조건 값 을 다시 테스트 해 야 합 니 다. 가장 좋 은 테스트 방법 은 pthread cond wait 함 수 를 순환 적 으로 호출 하고, 조건 을 만족 시 키 는 표현 식 을 순환 적 인 종료 조건 으로 설정 하 는 것 입 니 다. 예 를 들 어:
pthread_mutex_lock();
while (condition_is_false)
pthread_cond_wait();
pthread_mutex_unlock();
같은 조건 변수 에 있 는 서로 다른 스 레 드 가 방출 되 는 순 서 를 막 는 것 은 일정 하지 않다.
메모: pthread cond wait () 함 수 는 종료 점 입 니 다. 이 함 수 를 호출 할 때 걸 려 있 는 종료 요청 이 있 고 스 레 드 가 종료 할 수 있 습 니 다. 이 스 레 드 는 종료 되 고 사후 처리 함 수 를 실행 하기 시작 합 니 다. 이 때 조건 변수 와 관련 된 상호 배척 잠 금 은 잠 겨 있 습 니 다.
3. 조건 변수 에 있 는 차단 pthread cond signal 해제
#include
int pthread_cond_signal(pthread_cond_t *cv);
반환 값: 함수 가 0 을 성공 적 으로 되 돌려 주 었 습 니 다. 다른 반환 값 은 모두 오 류 를 표시 합 니 다.
함 수 는 지정 한 조건 변수 에 막 힌 스 레 드 를 방출 하 는 데 사 용 됩 니 다.
상호 배척 자물쇠 의 보호 하에 해당 하 는 조건 변 수 를 사용 해 야 합 니 다. 그렇지 않 으 면 조건 변수 에 대한 잠 금 해 제 는 잠 금 조건 변 수 를 잠 그 기 전에 발생 하여 잠 금 을 해제 할 수 있 습 니 다.
조건 변수 에 막 힌 모든 스 레 드 를 깨 우 는 순 서 는 스 케 쥴 러 정책 에 의 해 결 정 됩 니 다. 스 레 드 의 스 케 쥴 러 정책 이 SCHED OTHER 형식 이 라면 시스템 은 스 레 드 의 우선 순위 에 따라 스 레 드 를 깨 웁 니 다.
조건 변수 에 스 레 드 가 막 히 지 않 으 면 pthread cond signal () 을 호출 하 는 것 은 효과 가 없습니다.
4. 지 정 된 시간 까지 pthread cond timedwait 차단
#include
#include
int pthread_cond_timedwait(pthread_cond_t *cv,
pthread_mutex_t *mp, const structtimespec * abstime);
반환 값: 함수 가 0 을 성공 적 으로 되 돌려 주 었 습 니 다. 다른 반환 값 은 모두 오 류 를 표시 합 니 다.
함수 가 일정한 시간 이 되면 조건 이 발생 하지 않 아 도 차단 을 해제 합 니 다. 이 시간 은 매개 변수 abstime 에서 지정 합 니 다. 함수 가 돌아 올 때 해당 하 는 상호 배척 자 물 쇠 는 함수 가 잘못 되 더 라 도 잠 겨 있 습 니 다.
메모: pthread cond timedwait 함수 도 종료 점 입 니 다.
시간 초과 매개 변 수 는 하루 중 어느 시간 을 말 합 니 다. 예 를 들 어:
pthread_timestruc_t to;
to.tv_sec = time(NULL) + TIMEOUT;
to.tv_nsec = 0;
시간 초과 되 돌아 오 는 오류 코드 는 ETIMEDOUT 입 니 다.
5. 막 힌 모든 스 레 드 pthread cond broadcast 방출
#include
int pthread_cond_broadcast(pthread_cond_t *cv);
반환 값: 함수 가 0 을 성공 적 으로 되 돌려 주 었 습 니 다. 다른 반환 값 은 모두 오 류 를 표시 합 니 다.
함수 가 pthread cond wait 함수 에 의 해 특정한 조건 변수 에 막 힌 모든 스 레 드 를 깨 웁 니 다. 매개 변수 cv 는 이 조건 변 수 를 지정 하 는 데 사 용 됩 니 다. 스 레 드 가 이 조건 변수 에 막 히 지 않 았 을 때 pthread cond broadcast 함수 가 잘못 되 었 습 니 다.
pthread cond broadcast 함수 가 특정한 조건 변수 에 막 힌 모든 스 레 드 를 깨 우기 때문에 이 스 레 드 가 깨 어 난 후에 해당 하 는 상호 배척 자 물 쇠 를 다시 경쟁 하기 때문에 pthread cond broadcast 함 수 를 조심해 야 합 니 다.
6. 조건 변수 pthread cond destroy 방출
#include
int pthread_cond_destroy(pthread_cond_t *cv);
반환 값: 함수 가 0 을 성공 적 으로 되 돌려 주 었 습 니 다. 다른 반환 값 은 모두 오 류 를 표시 합 니 다.
방출 조건 변수.
메모: 조건 변수 가 차지 하 는 공간 이 풀 리 지 않 았 습 니 다.
7. 분실 문 제 를 일깨우다
스 레 드 가 서로 배척 하 는 자 물 쇠 를 얻 지 못 했 을 때 pthread cond signal 또는 pthread cond broadcast 함 수 를 호출 하면 분실 문 제 를 일 으 킬 수 있 습 니 다.
잃 어 버 린 것 을 깨 우 는 것 은 종종 아래 의 상황 에서 발생 한다.
pthread cond signal 또는 pthread cond broadcast 함 수 를 호출 합 니 다.
다른 스 레 드 는 테스트 조건 변수 와 pthread cond wait 함수 사이 에 있 습 니 다.
스 레 드 가 없 는 상태 에서 기다 리 고 있 습 니 다.
마지막 으로 두 개의 직접 실행 할 수 있 는 프로그램 으로 조건 변수의 운행 과정 을 더욱 잘 이해 할 수 있다.
(메모: 전체 프로그램의 실행 과정 을 검증 하기 위해 printf 문 구 를 여러 개 추가 하 였 습 니 다)
/*
: 。 ,
。 , , , 。
, 。
。 , 。
cond1.c
[root@mashang smb]# gcc cond1.c -o cond1 -lpthread
[root@mashang smb]# ./cond1
*/
#include
#include
#include
pthread_mutex_t count_lock;//
pthread_cond_t count_nonzero;//
unsigned count = 0;
void *decrement_count(void *arg)
{
pthread_mutex_lock(&count_lock);// :1 pthread_cond_wait
printf("decrement_count get count_lock
");
while(count == 0)
{
printf("decrement_count count == 0
");
printf("decrement_count before cond_wait
");
pthread_cond_wait(&count_nonzero, &count_lock);//2pthread_cond_wait ,
printf("decrement_count after cond_wait
");
}
printf("tid1:count--
");
count = count - 1;
printf("tid1:count= %d
", count);
pthread_mutex_unlock(&count_lock);
}
void *increment_count(void *arg)
{
pthread_mutex_lock(&count_lock); // :1 ( )
printf("increment_count get count_lock
");
if(count == 0)
{
printf("increment_count before cond_signal
");
pthread_cond_signal(&count_nonzero); //2pthread_cond_signal
printf("increment_count after cond_signal
");
}
printf("tid2:count++
");
count = count + 1;
printf("tid2:count= %d
", count);
pthread_mutex_unlock(&count_lock);//3 . pthread_cond_wait 。
}
int main(void)
{
pthread_t tid1, tid2;
pthread_mutex_init(&count_lock, NULL);
pthread_cond_init(&count_nonzero, NULL);
pthread_create(&tid1, NULL, decrement_count, NULL);
printf("tid1 decrement is created,begin sleep 2s
");
sleep(2);
printf("after sleep 2s, start creat tid2 increment
");
pthread_create(&tid2, NULL, increment_count, NULL);
printf("after tid2 increment is created,begin sleep 10s
");
sleep(5);
printf("after sleep 5s,begin exit!
");
pthread_exit(0);
return 0;
}
두 번 째 루틴:
/*
cond2.c
[root@mashang smb]# gcc cond2.c -o cond2 -lpthread
[root@mashang smb]# ./cond2 :
counter: 0 (1) counter 0 (main)
main1: before creating thd1 decrement (2) thd1, :
thd1 decrement get the lock , counter 0, (count_nonzero) .
thd1 decrement before cond_wait count_lock (wait , signal )
main2:thd1 is created, begin create thd2 increment (3) , thrd2, :
thd2 increment get the lock , counter 0, (count_nonzero) thrd1
thd2 increment before cond_signal count_lock,thrd1 .【signal ,wait 】
thd2 increment after cond_signal thd2 ,count++,
thd2 increment:counter = 1
thd1 decrement after cond_wait thrd1 , counter 0, 0 count_nonzero counter 1 .
thd1 decrement:counter = 0 .counter--
main3:after thd1 and thd2, begin sleep and exit! (4) , main
*/
#include
#include
#include
pthread_mutex_t counter_lock;
pthread_cond_t counter_nonzero;
int counter = 0;
int estatus = -1;
void *decrement_counter(void *argv);
void *increment_counter(void *argv);
int main(int argc, char **argv)
{
printf("counter: %d
", counter);
pthread_t thd1, thd2;
int ret;
printf("main1: before creating thd1 decrement
");
ret = pthread_create(&thd1, NULL, decrement_counter, NULL);// , pthread_cond_wait
if(ret){
perror("del:/n");
return 1;
}
printf("main2:thd1 is created, begin create thd2 increment
");
ret = pthread_create(&thd2, NULL, increment_counter, NULL);// , pthread_cond_signal
if(ret){
perror("inc: /n");
return 1;
}
printf("main3:after thd1 and thd2, begin sleep and exit!
");
sleep(3);
return 0;
}
void *decrement_counter(void *argv)
{
pthread_mutex_lock(&counter_lock);
printf("thd1 decrement get the lock
");
while(counter == 0)
{
printf("thd1 decrement before cond_wait
");
pthread_cond_wait(&counter_nonzero, &counter_lock);
printf("thd1 decrement after cond_wait
");
}
counter--;
printf("thd1 decrement:counter = %d
", counter);
pthread_mutex_unlock(&counter_lock);
return &estatus;
}
void *increment_counter(void *argv)
{
pthread_mutex_lock(&counter_lock);
printf("thd2 increment get the lock
");
if(counter == 0)
{
printf("thd2 increment before cond_signal
");
pthread_cond_signal(&counter_nonzero);
printf("thd2 increment after cond_signal
");
}
counter++;
printf("thd2 increment:counter = %d
", counter);
pthread_mutex_unlock(&counter_lock);
return &estatus;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.