您的位置:首页 > 健康 > 美食 > 泰安房产成交信息网_网站设计方案报价_百度学术官网入口_做网站比较好的公司有哪些

泰安房产成交信息网_网站设计方案报价_百度学术官网入口_做网站比较好的公司有哪些

2025/4/1 0:57:14 来源:https://blog.csdn.net/weixin_75197906/article/details/146451933  浏览:    关键词:泰安房产成交信息网_网站设计方案报价_百度学术官网入口_做网站比较好的公司有哪些
泰安房产成交信息网_网站设计方案报价_百度学术官网入口_做网站比较好的公司有哪些

线程同步——互斥锁

目录

一、基本概念

二、打印成对出现的字母

 三、生产者消费者(有限缓冲问题)

3.1 基本概念

3.2 代码实现 


一、基本概念

互斥锁是一种用于控制对共享资源访问的同步机制。它确保在同一时间内,只有一个线程可以访问被保护的资源。互斥锁有两个基本操作:

  1. 加锁(Lock):当一个线程需要访问共享资源时,它会尝试获取互斥锁。如果锁是可用的(即未被其他线程持有),则该线程成功获取锁并进入临界区(Critical Section),执行对共享资源的操作。如果锁已经被其他线程持有,则该线程会被阻塞,直到锁被释放。

  2. 解锁(Unlock):当线程完成对共享资源的操作后,它会释放互斥锁,允许其他等待的线程获取锁并访问共享资源。

二、打印成对出现的字母

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>//定义了一个全局互斥锁mutex,用于同步线程对共享资源的访问。
pthread_mutex_t mutex;//锁的使用在funa,funb 中
void* funa(void* arg)
{for(int i=0;i<5;i++){printf("A");fflush(stdout);int n=rand()%3;sleep(n);printf("A");//第二次打印代表对打印机的使用结束fflush(stdout);n=rand()%3;sleep(n);}
}void* funb(void* arg)
{for(int i=0;i<5;i++){printf("B");fflush(stdout);int n=rand()%3;sleep(n);printf("B");//第二次打印代表对打印机的使用结束fflush(stdout);n=rand()%3;sleep(n);}
}int main()
{//初始化全局互斥锁mutex,第二个参数为NULL表示使用默认属性。pthread_mutex_init(&mutex,NULL);//锁的地址,锁的属性//启动俩个线程pthread_t id1,id2;pthread_create(&id1,NULL,funa,NULL);pthread_create(&id2,NULL,funb,NULL);//等待线程结束pthread_join(id1,NULL);pthread_join(id2,NULL);//销毁,锁变量的地址pthread_mutex_destroy(&mutex);
}

这个输出结果表明程序中存在线程同步问题,导致输出结果并不是预期的AABB

定义了一个全局互斥锁mutex,用于同步线程对共享资源的访问。

输出预期值AABBAABB 成对出现

需要加锁

prhread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);

 三、生产者消费者(有限缓冲问题)

3.1 基本概念

俩个或更多的线程共享同一个缓冲区,其中一个或多个线程作为“生产者”会不断的向缓冲区中添加数据,另一个或多个线程作为消费者从缓冲区中取走数据。

生产者和消费者必须互斥的使用缓冲区

缓冲区空时,消费者不能读取数据

缓冲区满时,生产者不能添加数据

s1 代表空闲空间有多少个 s2代表数据有多少个

如果在ps1之前加,那么所有人都不能操作缓冲区了 。先看有空间可不可以写入,有空间再加锁,否则加锁后操作不了缓冲区了。只要数据写入之后就立刻解锁释放

3.2 代码实现 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>#define BUF_SIZE 30
pthread_mutex_t mutex;
sem_t sem_full;//信号量
sem_t sem_empty;int in=0;//在那个数据可以写入数据
int out=0;//在那个可以读取
int buff[BUF_SIZE];//缓冲区
void* sc_fun(void* arg)
{for(int i=0;i<30;i++){sem_wait(&sem_empty);pthread_mutex_lock(&mutex);buff[in]=rand()%100;printf("生产者在%d位置产生数据:%d\n",in,buff[in]);in=(in+1)%BUF_SIZE;pthread_mutex_unlock(&mutex);sem_post(&sem_full);int n=rand()%3;sleep(n);}
}void* xf_fun(void* arg)
{for(int i=0;i<20;i++){sem_wait(&sem_full);pthread_mutex_lock(&mutex);printf("----------消费者在%d位置消费数据:%d\n",out,buff[out]);out=(out+1)%BUF_SIZE;pthread_mutex_unlock(&mutex);sem_post(&sem_empty);//让空闲格子加1int n=rand()%3;sleep(n);}
}int main()
{pthread_mutex_init(&mutex,NULL);sem_init(&sem_full,0,0);//信号量初始化sem_init(&sem_empty,0,BUF_SIZE);//为空的有多少个pthread_t sc_id[2];pthread_t xf_id[3];for(int i=0;i<2;i++){pthread_create(&sc_id[i],NULL,sc_fun,NULL);}for(int i=0;i<3;i++){pthread_create(&xf_id[i],NULL,xf_fun,NULL);}for(int i=0;i<2;i++){pthread_join(sc_id[i],NULL);}for(int i=0;i<3;i++){pthread_join(xf_id[i],NULL);}pthread_mutex_destroy(&mutex);sem_destroy(&sem_full);sem_destroy(&sem_empty);exit(0);
}
  • sem_fullsem_empty 是信号量,分别表示缓冲区中已占用的位置数和空闲位置数。

  • inout 分别表示下一个可写和可读的位置。

  • buff 是缓冲区数组,用于存储数据。

  • 输出中可以看到生产者和消费者线程交替进行操作,这表明它们在并发环境中工作。

  • 生产者在生产数据前会等待一个空闲位置(sem_wait(&sem_empty)),然后锁定互斥锁,生产数据,解锁互斥锁,并释放一个已占用位置(sem_post(&sem_full))。

  • 消费者在消费数据前会等待一个已占用位置(sem_wait(&sem_full)),然后锁定互斥锁,消费数据,解锁互斥锁,并释放一个空闲位置(sem_post(&sem_empty))。

  • 已占用:表示该位置已经被生产者放入了数据,并且这些数据尚未被消费者取出。缓冲区中已经被生产者放入数据的位置。缓冲区可以被看作是一个固定大小的数组,用于临时存储生产者生成的数据,直到消费者将其取出。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com