Linux 스레드 간 통신을 위한 조건 변수 (17)

1. 조건변수

뮤텍스와 달리 조건 변수는 잠금보다는 대기에 사용되며 조건 변수 자체는 잠금이 아닙니다! 조건 변수는 특별한 조건이 발생할 때까지 스레드를 자동으로 차단하는 데 사용됩니다. 일반적으로 조건 변수와 뮤텍스 잠금은 함께 사용됩니다. 조건 변수의 두 가지 작업:
(1) 조건이 충족되지 않아 스레드가 차단됩니다.
(2) 조건이 만족되면 차단된 스레드에 작업을 시작하도록 알립니다. 조건변수 유형: pthreadcondt.

2. 조건변수 초기화 기능

	int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);

기능:
조건 변수를 초기화합니다.

매개변수:
cond: 초기화할 조건 변수에 대한 포인터.
attr: 조건 변수 속성(일반적으로 기본값)은 NULL을 전달하거나 정적 초기화 방법을 사용하여 조건 변수를 초기화합니다.

    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

반환 값:
성공: 0.
실패: 0이 아님, 오류 번호.

3. 해제 조건 변수 기능

	int pthread_cond_destroy(pthread_cond_t *cond);

기능:
조건 변수를 삭제합니다.

매개변수:
cond: 초기화할 조건 변수에 대한 포인터.

반환 값:
성공: 0.
실패: 0이 아님, 오류 번호.

4. 대기 조건 기능

	int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

기능:
조건 변수를 기다리는 블록입니다.
a) 조건 변수 cond(참조 1)가 충족될 때까지 차단하고 기다리는 것
b) 마스터된 뮤텍스 잠금 해제(뮤텍스 잠금 해제)는 pthread_mutex_unlock(&mutex)와 동일합니다.
여기서 a) b) 두 단계는 원자적 작업입니다.
c) 활성화되고 pthread_cond_wait 함수가 반환되면 차단을 해제하고 뮤텍스 pthread_mutex_lock(&mutex)를 다시 적용합니다.

매개변수:
cond: 초기화할 조건 변수에 대한 포인터.
mutex: 상호 배제 잠금.

반환 값:
성공: 0.
실패: 0이 아님, 오류 번호.

5. 시간 제한 대기 조건 기능

	int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct *restrict abstime);

기능:
제한된 시간 내에 조건 변수를 기다립니다.

매개변수:
cond: 초기화할 조건 변수에 대한 포인터.
mutex: 상호 배제 잠금.
절대 시간: 절대 시간.

반환 값:
성공: 0.
실패: 0이 아님, 오류 번호.

6. 조건 변수를 기다리고 있는 스레드를 깨웁니다.

	int pthread_cond_signal(pthread_cond_t *cond);

기능:
조건 변수에서 차단된 하나 이상의 스레드를 깨웁니다.

매개변수:
cond: 초기화할 조건 변수를 가리킵니다.

반환 값:
성공: 0.
실패: 0이 아님, 오류 번호.

설명하다:

	int pthreadcondbroadcast(pthreadcondt *cond); 功能: 给阻塞在条件变量上的所有线程发送信号 参数: cond 条件变量的地址

7. 참조 코드

//=============================================================================
// File Name    : thread_cond.c
// Author       : FengQQ
//
// Description  : 条件变量
// Annotation   : 与互斥锁不同,条件变量是用来等待而不是用来上锁的,
//				  条件变量本身不是锁!条件变量用来自动阻塞一个线程,
//				  直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。
//				  条件变量的两个动作:1)条件不满, 阻塞线程 。
//								      2)当条件满足, 通知阻塞的线程开始工作。
//				  条件变量的类型: pthreadcondt。
//
//				  《条件变量实现生产者与消费者代码》
//
// Created by FengQQ. 2020-10-05
//=============================================================================
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>

#define BUFFER_SIZE		5					//生产库存大小
#define PRODUCT_CNT		30					//产品生产总数

typedef struct product_cons_t
{
    
    
	int buffer[BUFFER_SIZE];				//生产产品值
	pthread_mutex_t lock;					//互斥锁 volatile int
	int readpos,writepos;					//读写位置
	pthread_cond_t notempty;				//条件变量,为空
	pthread_cond_t notfull;					//非满
}Product_Cons_T;

Product_Cons_T product_cons;

void init(Product_Cons_T *p)
{
    
    
	pthread_mutex_init(&p->lock,NULL);		//互斥锁
	pthread_cond_init(&p->notempty,NULL);	//条件变量
	pthread_cond_init(&p->notfull,NULL);	//条件变量
	p->readpos = 0;							//读写位置
	p->writepos = 0;
}

void finish(Product_Cons_T *p)
{
    
    
	pthread_mutex_destroy(&p->lock);		//互斥锁
	pthread_cond_destroy(&p->notempty);		//条件变量
	pthread_cond_destroy(&p->notfull);		//条件变量
	p->readpos = 0;							//读写位置
	p->writepos = 0;
}

//-------------生产一个数据--------------
void put(Product_Cons_T *p,int data)		//输入产品子函数
{
    
    
	pthread_mutex_lock(&p->lock);
	if((p->writepos+1)%BUFFER_SIZE == p->readpos)
	{
    
    
		printf("product wait for not full\r\n");
		pthread_cond_wait(&p->notfull,&p->lock);
	}
	
	p->buffer[p->writepos] = data;
	(p->writepos)++;
	if(p->writepos >= BUFFER_SIZE)
		p->writepos = 0;
	
	pthread_cond_signal(&p->notempty);
	pthread_mutex_unlock(&p->lock);
}
//-------------取出一个数据--------------
int get(Product_Cons_T *p)					//输入产品子函数
{
    
    
	int data;
	
	pthread_mutex_lock(&p->lock);
	if(p->readpos == p->writepos)
	{
    
    
		printf("consumer wait for not empty\r\n");
		pthread_cond_wait(&p->notempty,&p->lock);
	}
	data = p->buffer[p->readpos];
	(p->readpos)++;
	if(p->readpos >= BUFFER_SIZE)
		p->readpos = 0;
	
	pthread_cond_signal(&p->notfull);
	pthread_mutex_unlock(&p->lock);
	
	return data;
}
//-----------------生产者线程-----------------
void *pthread_product(void *arg)
{
    
    
	int n;
	for(n=1;n<=50;++n)
	{
    
    
		sleep(1);
		printf("put the %d product...\r\n",n);
		put(&product_cons,n);
		printf("put the %d product success\r\n",n);
	}
	printf("product stopped\r\n");
	
	return NULL;

}
//-----------------消费者线程-----------------
void *pthread_consumer(void *arg)
{
    
    
	static int cnt = 0;
	int num;
	while(1)
	{
    
    
		sleep(2);
		printf("get product...\r\n");
		num = get(&product_cons);
		printf("get the %d product success\r\n",num);
		if(++cnt == PRODUCT_CNT)
			break;
	}
	printf("consumer stopped\r\n");
	
}

int main(int argc,char *argv[])
{
    
    
	int ret;
	pthread_t ptid1,ptid2;
	
	init(&product_cons);										//初始化相关操作
	
	ret = pthread_create(&ptid1,NULL,pthread_product,NULL);		//创建线程1
	if(ret != 0)
	{
    
    
		printf("create new pthread product failed...\r\n");
		return -1;
	}
	
	ret = pthread_create(&ptid2,NULL,pthread_consumer,NULL);	//创建线程2	
	if(ret != 0)
	{
    
    
		printf("create new pthread consumer failed...\r\n");
		return -1;
	}
	
	ret = pthread_join(ptid1,NULL);								//回收线程1资源
	if(ret != 0)
	{
    
    
		printf("pthread product join failed...\r\n");
	}
	
	ret = pthread_join(ptid2,NULL);								//回收线程2资源
	if(ret != 0)
	{
    
    
		printf("pthread consumer join failed...\r\n");
	}
	
	finish(&product_cons);										//释放相关操作
	
	return 0;
}


Linux 스레드 간 통신을 위한 신호 (18)

링크: 링크 .(https://blog.csdn.net/qq_39721016/article/details/120478269?spm=1001.2014.3001.5501)

추천

출처blog.csdn.net/qq_39721016/article/details/120477932