Linux--조건 변수(조건 변수)는 생산자-소비자 모델 및 읽기-쓰기 잠금을 구현합니다.
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 }
읽기-쓰기 잠금은 실제로 더 많이 읽고 더 적게 쓰는 상황을 처리하는 데 사용되는 특수 스핀 잠금입니다. 이는 공유 리소스에 대한 방문자를 독자와 작성자로 구분합니다. 독자는 공유 리소스에 대한 읽기 권한만 갖습니다. . 작성자는 공유 리소스에 작성해야 합니다. 이러한 종류의 잠금은 스핀 잠금에 비해 동시성을 향상시킬 수 있습니다. 다중 프로세서 시스템에서는 여러 판독기가 동시에 공유 리소스에 액세스할 수 있고 가능한 최대 판독기 수가 실제 논리 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 }

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Centos와 Ubuntu의 주요 차이점은 다음과 같습니다. Origin (Centos는 Red Hat, Enterprise의 경우, Ubuntu는 Debian에서 시작하여 개인의 경우), 패키지 관리 (Centos는 안정성에 중점을 둡니다. Ubuntu는 APT를 사용하여 APT를 사용합니다), 지원주기 (Ubuntu는 5 년 동안 LTS 지원을 제공합니다), 커뮤니티에 중점을 둔다 (Centos Conciors on ubuntu). 튜토리얼 및 문서), 사용 (Centos는 서버에 편향되어 있으며 Ubuntu는 서버 및 데스크탑에 적합), 다른 차이점에는 설치 단순성 (Centos는 얇음)이 포함됩니다.

CentOS 설치 단계 : ISO 이미지를 다운로드하고 부팅 가능한 미디어를 실행하십시오. 부팅하고 설치 소스를 선택하십시오. 언어 및 키보드 레이아웃을 선택하십시오. 네트워크 구성; 하드 디스크를 분할; 시스템 시계를 설정하십시오. 루트 사용자를 만듭니다. 소프트웨어 패키지를 선택하십시오. 설치를 시작하십시오. 설치가 완료된 후 하드 디스크에서 다시 시작하고 부팅하십시오.

Centos는 중단되었으며 대안은 다음과 같습니다. 1. Rocky Linux (Best Compatibility); 2. Almalinux (Centos와 호환); 3. Ubuntu 서버 (구성 필수); 4. Red Hat Enterprise Linux (상업용 버전, 유료 라이센스); 5. Oracle Linux (Centos 및 Rhel과 호환). 마이그레이션시 고려 사항은 호환성, 가용성, 지원, 비용 및 커뮤니티 지원입니다.

Docker Desktop을 사용하는 방법? Docker Desktop은 로컬 머신에서 Docker 컨테이너를 실행하는 도구입니다. 사용 단계는 다음과 같습니다. 1. Docker Desktop 설치; 2. Docker Desktop을 시작하십시오. 3. Docker 이미지를 만듭니다 (Dockerfile 사용); 4. Docker Image 빌드 (Docker 빌드 사용); 5. 도커 컨테이너를 실행하십시오 (Docker Run 사용).

Docker는 Linux 커널 기능을 사용하여 효율적이고 고립 된 응용 프로그램 실행 환경을 제공합니다. 작동 원리는 다음과 같습니다. 1. 거울은 읽기 전용 템플릿으로 사용되며, 여기에는 응용 프로그램을 실행하는 데 필요한 모든 것을 포함합니다. 2. Union 파일 시스템 (Unionfs)은 여러 파일 시스템을 스택하고 차이점 만 저장하고 공간을 절약하고 속도를 높입니다. 3. 데몬은 거울과 컨테이너를 관리하고 클라이언트는 상호 작용을 위해 사용합니다. 4. 네임 스페이스 및 CGroup은 컨테이너 격리 및 자원 제한을 구현합니다. 5. 다중 네트워크 모드는 컨테이너 상호 연결을 지원합니다. 이러한 핵심 개념을 이해 함으로써만 Docker를 더 잘 활용할 수 있습니다.

Centos가 중단 된 후 사용자는 다음과 같은 조치를 취할 수 있습니다. Almalinux, Rocky Linux 및 Centos 스트림과 같은 호환되는 분포를 선택하십시오. Red Hat Enterprise Linux, Oracle Linux와 같은 상업 분포로 마이그레이션합니다. Centos 9 Stream : 롤링 분포로 업그레이드하여 최신 기술을 제공합니다. Ubuntu, Debian과 같은 다른 Linux 배포판을 선택하십시오. 컨테이너, 가상 머신 또는 클라우드 플랫폼과 같은 다른 옵션을 평가하십시오.

실패한 Docker 이미지 빌드에 대한 문제 해결 단계 : Dockerfile 구문 및 종속성 버전을 확인하십시오. 빌드 컨텍스트에 필요한 소스 코드 및 종속성이 포함되어 있는지 확인하십시오. 오류 세부 사항에 대한 빌드 로그를보십시오. -표적 옵션을 사용하여 계층 적 단계를 구축하여 실패 지점을 식별하십시오. 최신 버전의 Docker Engine을 사용하십시오. -t [image-name] : 디버그 모드로 이미지를 빌드하여 문제를 디버깅하십시오. 디스크 공간을 확인하고 충분한 지 확인하십시오. 빌드 프로세스에 대한 간섭을 방지하기 위해 Selinux를 비활성화하십시오. 커뮤니티 플랫폼에 도움을 요청하고 Dockerfiles를 제공하며보다 구체적인 제안을 위해 로그 설명을 구축하십시오.

대 코드 시스템 요구 사항 : 운영 체제 : Windows 10 이상, MacOS 10.12 이상, Linux 배포 프로세서 : 최소 1.6GHz, 권장 2.0GHz 이상의 메모리 : 최소 512MB, 권장 4GB 이상의 저장 공간 : 최소 250MB, 권장 1GB 및 기타 요구 사항 : 안정 네트워크 연결, Xorg/Wayland (LINUX)
