Linux--조건 변수(조건 변수)는 생산자-소비자 모델 및 읽기-쓰기 잠금을 구현합니다.

黄舟
풀어 주다: 2023-03-04 22:32:01
원래의
2296명이 탐색했습니다.

1. 조건 변수
스레드 동기화 프로세스 중에는 다음과 같은 상황도 있습니다. 스레드 A는 실행을 계속하기 전에 특정 조건이 성립될 때까지 기다려야 합니다. 조건이 성립되지 않으면 스레드 A가 실행됩니다. 스레드 B가 실행되는 동안 차단됩니다. 프로세스 중에 이 조건이 설정되면 스레드 A가 실행을 계속하기 위해 깨어납니다. Pthread 라이브러리의 조건 변수를 사용하여 조건 대기를 차단하거나 이 조건을 기다리는 스레드를 깨울 수 있습니다. 조건 변수는 pthread_cond_t 유형의 변수로 표시됩니다.

pthread_cond_init를 사용하여 조건 변수를 정적으로 할당한 경우 매크로 정의 PTHEAD_COND_INITIALIZER를 사용하여 초기화하고 pthread_cond_destroy를 사용하여 조건 변수를 삭제할 수 있습니다. 실패하면 오류 번호가 반환됩니다.
조건 변수는 항상 Mutex와 함께 사용됩니다. 스레드는 pthread_cond_wait를 호출하여 조건 변수를 차단하고 대기할 수 있습니다.
1. Mutex를 해제하고
3. 깨어나면 Mutex를 다시 획득합니다. return
스레드는 pthread_cond_signal을 호출하여 특정 조건 변수를 기다리는 다른 스레드를 깨울 수도 있고, pthread_cond_broadcast를 호출하여 이 조건 변수를 기다리는 모든 스레드를 깨울 수도 있습니다.
2. 생산자-소비자 모델을 사용하여 설명합니다.
이름에서 알 수 있듯이 이 모델을 구현하려면 먼저 두 가지 역할(생산자, 소비자)이 있어야 합니다. 물론 두 가지 중요한 자원에 모두 접근할 수 있는 계기가 있어야 하며(1회), 생산자와 소비자의 관계(상호 배제)와 소비자의 관계(상호 배제), 생산자와 소비자의 관계를 이해해야 합니다. (동기화와 상호 배제)는 일반적으로 한 장소, 두 역할, 세 가지 관계를 의미합니다. 이를 코드로 구현하기 위해 생산자는 데이터 조각을 생성한 다음 소비자에게 소비하라는 신호를 보냅니다. 소비자가 이를 소비한 후에는 생산자에게 생산을 계속하라는 신호를 보내는 식입니다.

1 #include<stdio.h>  
  2 #include <stdlib.h>  
  3 #include<malloc.h>  
  4 #include<pthread.h>                                                                                                                               
  5 #include<semaphore.h>  
  6 typedef int Data_type;  
  7 typedef int* Data_type_p;  
  8 static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;//初始化互斥锁  
  9 static pthread_cond_t needProduct=PTHREAD_COND_INITIALIZER;//初始化条件变量  
 10   
 11  
 12 typedef struct listnode //定义一个链表来存放数据(一个场所)  
 13 {  
 14     Data_type data;  
 15     struct listnode* next;  
 16 }list ,*listp,**listpp;  
 17   
 18 listp head=NULL;  
 19   
 20 static listp buyNode(Data_type _data)  
 21 {  
 22     listp tem=(listp)malloc(sizeof(list));  
 23     if(tem)  
 24     {  
 25         tem -> data=_data;  
 26         tem -> next=NULL;  
 27         return tem;  
 28     }  
 29     return NULL;  
 30 }  
 31 void initList(listpp list)  
 32 {  
 33     *list=buyNode(0);  
 34 }  
 35 void push_list(listp list,Data_type _data)  
 36 {  
 37     listp cur=buyNode(_data);  
 38     listp tem=list;  
 39     while(tem->next)  
 40     {  
 41         tem=tem->next;  
 42     }  
 43     tem ->next=cur;  
 44 }  
 45 void deleteList(listp list)  
 46 {  
 47     if(list)  
 48     {  
 49         free(list);  
 50         list=NULL;  
 51     }  
 52 }  
 53 int pop_list(listp list,Data_type_p data)  
 54 {  
 55     if(list ->next==NULL)  
 56     {  
 57         *data =-1;  
 58         return -1;  
 59     }  
 60     listp tem=list->next;  
 61     list ->next=tem->next;  
 62     *data=tem->data;  
 63     deleteList(tem);  
 64     return 0;  
 65 }  
 66 void PrintList(listp list)  
 67 {  
 68     listp cur=list->next;;  
 69     while(cur)  
 70     {  
 71         printf("%d",cur->data);  
 72         fflush(stdout);  
 73         cur=cur->next;  
 74     }  
 75     printf("\n");  
 76 }  
 77 void *product(void* arg)//定义生产者与生产者之间的关系(互斥)  
 78 {  
 79     int i=0;  
 80     while(1)  
 81     {  
 82         pthread_mutex_lock(&lock);  
 83         printf("product data:%d\n",i);  
 84         push_list(head,i++);  
 85         pthread_mutex_unlock(&lock);  
 86         printf("conduct is ok.weak up comsumer...\n");  
 87         pthread_cond_signal(&needProduct);//当生产者有数据时,发送信号,唤醒消费者  
 88         sleep(2);  
 89     }  
 90   
 91 }  
 92 void *consumer(void* arg)//消费者与消费者之间的关系(互斥)  
 93 {  
 94     Data_type _data;  
 95     while(1)  
 96     {     
 97         pthread_mutex_lock(&lock);  
 98         while(-1==pop_list(head,&_data))  
 99         {  
100             pthread_cond_wait(&needProduct,&lock);//没收到生产者的消息之前就阻塞等待  
101         }  
102         printf("consumer data:%d\n",_data);  
103         pthread_mutex_unlock(&lock);  
104         sleep(1);  
105     }  
106 }  
107 int main()  
108 {  
109     initList(&head);  
110     pthread_t id1;  
111     pthread_t id2;  
112     pthread_create(&id1,NULL,product,NULL);  
113     pthread_create(&id2,NULL,consumer,NULL);  
114     pthread_join(id1,NULL);  
115     pthread_join(id2,NULL);  
116     return 0;  
117 }
로그인 후 복사

요약: 위 코드는 단일 생산자와 단일 소비자, 즉 생산자-소비자 모델을 구현합니다. 간단히 말해서 생산자와 생산자, 소비자와 소비자 사이의 상호 배제를 달성하는 것입니다. 상호 배타적인 관계가 있습니다. 생산자와 소비자 사이, 그리고 생산자와 소비자 사이의 동기화된 상호 배타적 관계.


3. 세마포어를 사용하여 생산자-소비자 모델 구현
Mutex 변수는 0 또는 1이며 초기화 시 Mutex가 1임을 나타냅니다. ,
잠금 시 리소스를 획득하고 Mutex를 0으로 줄여 사용 가능한 리소스가 더 이상 없음을 나타내고 잠금 해제 시 리소스를 해제하고 Mutex를 다시 1로 늘려 사용 가능한 다른 리소스가 있음을 나타냅니다. 세마포어는 Mutex와 유사하며 사용 가능한 리소스 수를 나타냅니다. Mutex와 달리 이 숫자는 1보다 클 수 있습니다. 즉, 세마포어가 기술하는 자원의 개수가 1개라면 이때의 세마포어와 뮤텍스 락은 동일하다!
sem_init()는 세마포어를 초기화합니다

sem_wait()P 작업은 리소스를 얻습니다

sem_post()V 작업은 리소스를 해제합니다

sem_destroy()는 세마포어를 파괴합니다

위는 연결리스트로 작성된 생산자-소비자 모델이며, 그 공간은 동적으로 할당됩니다. 이제 생산자-소비자 모델은 고정 크기 링 큐를 기반으로 다시 작성됩니다

1 #include<stdio.h>  
  2 #include<pthread.h>  
  3 #include<semaphore.h>  
  4 #define PRODUCT_SIZE 20  
  5 #define CONSUMER_SIZE 0  
  6   
  7 sem_t produceSem;  
  8 sem_t consumerSem;  
  9 int Blank [PRODUCT_SIZE];  
 10   
 11 void* product(void* arg)  
 12 {  
 13     int p=0;  
 14     while(1)  
 15     {  
 16         sem_wait(&produceSem); //申请资源。  
 17         int _product=rand()%100;  
 18         Blank[p]=_product;  
 19         printf("product is ok ,value is :%d\n",_product);  
 20         sem_post(&consumerSem);//释放资源  
 21         p=(p+1) % PRODUCT_SIZE;  
 22         sleep(rand()%3);  
 23     }  
 24   
 25 }  
 26 void* consumer(void* arg)  
 27 {  
 28     int p=0;  
 29     while(1)  
 30     {  
 31         sem_wait(&consumerSem);//申请资源  
 32         int _consumer=Blank[p];  
 33         printf("consumer is ok,value is :%d\n",_consumer);  
 34         sem_post(&produceSem);//释放资源  
 35         p=(p+1)% PRODUCT_SIZE;  
 36         sleep(rand()%5);  
 37     }  
 38 }  
 39 int main()  
 40 {   sem_init(&produceSem,0,PRODUCT_SIZE);  
 41     sem_init(&consumerSem,0,CONSUMER_SIZE);  
 42     pthread_t tid1,tid2;  
 43     pthread_create(&tid1,NULL,product,NULL);  
 44     pthread_create(&tid2,NULL,consumer,NULL);  
 45     pthread_join(tid1,NULL);  
 46     pthread_join(tid2,NULL);  
 47     sem_destroy(&produceSem);  
 48     sem_destroy(&consumerSem);  
 49     return 0;  
 50 }
로그인 후 복사

4. 읽기 -write lock

읽기-쓰기 잠금은 실제로 더 많이 읽고 더 적게 쓰는 상황을 처리하는 데 사용되는 특수 스핀 잠금입니다. 이는 공유 리소스에 대한 방문자를 독자와 작성자로 구분합니다. 독자는 공유 리소스에 대한 읽기 권한만 갖습니다. . 작성자는 공유 리소스에 작성해야 합니다. 이러한 종류의 잠금은 스핀 잠금에 비해 동시성을 향상시킬 수 있습니다. 다중 프로세서 시스템에서는 여러 판독기가 동시에 공유 리소스에 액세스할 수 있고 가능한 최대 판독기 수가 실제 논리 CPU 수이기 때문입니다. 쓰기기는 배타적입니다. 읽기-쓰기 잠금은 동시에 하나의 쓰기기 또는 여러 읽기기만 가질 수 있지만(CPU 수와 관련하여) 동시에 읽기기와 쓰기기를 모두 가질 수는 없습니다. 읽기-쓰기 잠금도 세 가지 관계를 따릅니다. 즉, 판독기-작성기(상호 배타적 및 동기화), 판독기-판독기(관계 없음), 기록기-작성기(상호 배타적) 개체 2개(판독기와 기록기), 위치 1개입니다.
pthread_rwlock_wrlock 쓰기 모드, 성공 시 0 반환, 실패 시 오류 코드

pthread_rwlock_rdlock 읽기 모드, 성공 시 0 반환, 실패 시 오류 코드

pthread_rwlock_init 초기화

1 #include<stdio.h>  
  2 #include<pthread.h>  
  3 #define _READNUM_ 2  
  4 #define _WREITENUM_ 3  
  5 pthread_rwlock_t lock;  
  6 int buf=0;  
  7 void* read(void* reg)  
  8 {  
  9     while(1)  
 10     {  
 11         if(pthread_rwlock_tryrdlock(&lock) != 0)//读方式  
 12         {  
 13             printf("writer is write! reader wait...\n");  
 14         }  
 15         else  
 16         {  
 17             printf("reader is reading,val is %d\n",buf);  
 18             pthread_rwlock_unlock(&lock);  
 19         }  
 20         sleep(2);  
 21     }  
 22 }  
 23 void* write(void* reg)  
 24 {  
 25     while(1)  
 26     {  
 27         if(pthread_rwlock_trywrlock(&lock) != 0)//写方式  
 28         {  
 29             printf("reader is reading ! writer wait...\n");  
 30             sleep(1);  
 31         }  
 32         else  
 33         {  
 34             buf++;  
 35             printf("writer is writing,val is %d\n",buf);  
 36             pthread_rwlock_unlock(&lock);  
 37   
 38         }  
 39         sleep(1);  
 40     }  
 41 }  
 42 int main()  
 43 {  
 44     pthread_rwlock_init(&lock,NULL);  
 45     pthread_t tid;  
 46     int i=0;  
 47     for(i;i< _WREITENUM_;i++)  
 48     {  
 49         pthread_create(&tid,NULL,write,NULL);  
 50     }  
 51   
 52     for(i; i< _READNUM_;i++)  
 53     {  
 54         pthread_create(&tid,NULL,read,NULL);  
 55     }  
 56         pthread_join(tid,NULL);  
 57         sleep(100);  
 58         return 0;  
 59 }
로그인 후 복사

위는 Linux입니다. 조건 변수(조건 변수)는 생산자-소비자 모델과 읽기-쓰기 잠금 내용을 구현합니다. 더 많은 관련 내용은 PHP 중국어 웹사이트(www.php.cn)를 참고하세요!


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿