上一篇文章中,我们通过增加一个变量作为标识,从而判断出读者和写者所共享的缓冲区是否有内容,从而实现读写交替,而不是一个线程不停的运行,另外一个“饿死”。
实际上,操作系统里出了互斥锁,还提供了信号量来实现并发情况下的同步。
/**
**读写互斥问题
**读的时候不能写,写的时候不能读
**读写交替(使用信号量)
**/
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
//声明一把互斥锁
pthread_mutex_t mutex;
sem_t sem;
void writer(void)
{
while(1)
{
sem_post(&sem);//V操作,信号量+1
pthread_mutex_lock(&mutex);//加锁
printf("writer加锁成功,开始写...\n");
sleep(5);
printf("writer写操作结束,释放互斥锁\n");
pthread_mutex_unlock(&mutex);//释放互斥锁
}
}
void reader(void)
{
while(1)
{
sem_wait(&sem);//P操作,信号量-1
pthread_mutex_lock(&mutex);//加锁
printf("reader加锁成功,开始读...\n");
sleep(5);
printf("reader读操作结束,释放互斥锁\n");
pthread_mutex_unlock(&mutex);//释放互斥锁
}
}
int main(void)
{
printf("初始化互斥锁\n");
pthread_mutex_init(&mutex,NULL);
printf("初始化信号量\n");
sem_init(&sem,0,0);
pthread_t thread_writer;
pthread_t thread_reader;
printf("开始读写线程\n");
pthread_create(&thread_reader,NULL,(void *)reader,NULL);
pthread_create(&thread_writer,NULL,(void *)writer,NULL);
printf("回收线程\n");
pthread_join(thread_reader,NULL);
pthread_join(thread_writer,NULL);
printf("运行结束\n");
return 0;
}
这里我们通过引入信号量(sem_t )类型的变量来解决共享缓冲区判断问题,这里要注意的一个地方是PV操作的位置以及互斥锁的加锁和信号量的PV操作顺序问题。
首先讨论一下PV操作的位置。P在我们的程序中就是sem_post()函数,作用是对信号量进行加1,这里很显然我们应该将P操作放在写者的线程中。同理,读者中的sem_wait()函数代表的就是V操作,作用是对信号量进行减1,很显然应该放在读者线程中。
关于PV操作和加锁的先后顺序。我最开始是先加锁,再进行P或者V,但是运行的时候我发现程序完全阻塞了,没有任何输出,分析了一下原因:如果是读者先加锁,加锁成功,然后进行V操作,这个时候因为信号量初始值为0,所以进入阻塞。我们再来看写者会是什么情况,写者试图加锁,因为读者已经加锁了,所以阻塞。至此,两个线程全部阻塞。。。所以要注意,一定是先P或者V操作,再进行加锁,否则会造成全部阻塞的死锁现象。
分享到:
相关推荐
操作系统中的线程同步是多线程编程中一个关键的概念,它确保了多个线程在访问共享资源时的正确性,防止数据竞争和其他并发问题。在Windows操作系统中,提供了多种线程同步机制,如临界区、事件、信号量以及互斥量等...
本文将深入探讨三种常见的帧同步算法,并提供MATLAB代码实现,适合本科毕设项目参考。 1. **滑动窗口同步(Sliding Window Synchronization)** 滑动窗口同步是一种基本的同步方法,它依赖于在接收数据中寻找特定...
在操作系统的设计与实现中,有十大核心算法,这些算法对于理解和优化操作系统至关重要。让我们深入探讨这些算法及其重要性。 1. **调度算法**:调度是操作系统管理处理器的关键部分,包括进程调度、I/O调度等。短...
操作系统_进程同步算法习题精选.ppt
在操作系统的设计与实现中,算法起着至关重要的作用。本篇文章将深入探讨标题中提及的几个关键算法:多级调度算法、银行家算法、磁盘调度算法以及生产者-消费者问题。 1. **多级调度算法**: 多级调度算法是操作...
在操作系统的设计与实现中,有三个重要的算法:银行家算法、进程调度算法和页面置换算法。这些算法对于系统的性能和稳定性至关重要。 首先,让我们深入探讨银行家算法。这个算法主要用于预防操作系统的死锁问题。...
3.内容:基于5G通信系统的时间同步算法matlab仿真。 5G通信系统的时间同步需求主要源于对基站空口时间偏差的严格限定,这主要是为了避免上下行时隙干扰。对于4G TDD系统,采用固定子载波间隔15kHz,保护周期GP...
实验一、进程控制实验 ...实验三、进程调度算法实验 实验四、进程同步实验 实验五、进程互斥实验 实验六、死锁问题实验 实验七、内存页面置换算法实验 实验八、磁盘移臂调度算法实验 实验九、文件系统接口实验
分布式操作系统算法Demo是一种高级操作系统技术的实践展示,它涵盖了分布式系统和算法的核心概念。在现代计算机科学中,分布式操作系统是连接多台独立计算机,通过网络通信实现资源共享和协同工作的系统。这种系统...
这个压缩包包含的是一系列用Java语言编写的操作系统经典算法,对于学习和理解操作系统的工作原理极其有价值。 1. **进程管理**: - **进程创建与销毁**:Java代码可能实现了创建新进程和结束进程的逻辑,这涉及到...
在这个"操作系统实验各类算法的程序"压缩包中,我们很可能会找到一系列与操作系统原理相关的代码实现,这些代码通常会涵盖以下几个关键知识点: 1. **进程管理**:在操作系统中,进程是程序的执行实例。这里可能...
本主题将详细探讨基于MATLAB的无线传感器网络时间同步算法。 MATLAB是一种强大的开发环境,适用于数值计算、符号计算以及算法开发。在无线传感器网络时间同步领域,MATLAB可以用来设计、模拟和测试各种同步算法,如...
在这个【操作系统各个算法模拟实现【java版】】项目中,开发者通过Java语言和JSP(JavaServer Pages)以及线程技术,模拟了操作系统的几个关键算法,包括文件管理系统和内存分配策略,以帮助学习者更好地理解和应用...
OFDM(Orthogonal Frequency Division Multiplexing,...总之,"OFDM经典同步算法MATLAB程序"是一个实用的学习资源,可以帮助工程师和学生了解并实践OFDM系统中的关键同步步骤,提升无线通信领域的理论知识和编程技能。
本资源“操作系统原理算法C语言实现”为学习操作系统原理提供了实用的C语言代码示例,下面将详细探讨其中可能涵盖的知识点。 1. 进程管理:操作系统中的进程是程序执行的实例,涉及的概念包括进程创建、撤销、状态...
操作系统是管理计算机硬件和软件资源的核心程序,而死锁是多进程环境中的一种常见问题,它发生在两个或多个进程互相等待对方释放资源而无法继续执行的情况。银行家算法是由E.F.科恩提出的,用于预防操作系统中的死锁...
在这个主题中,我们探讨了几个关键的操作系统算法,它们对于理解和优化系统的性能至关重要。 1. FIFO(先进先出)算法:这是一种最简单的页面替换算法,按照内存中的页面到达顺序进行淘汰。当内存满时,最先进入...
本实验要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。 三. 实验题目 模拟PV操作同步机构,且用PV操作解决生产者—消费者问题。 运行环境:Microsoft Visual Studio ...
操作系统实验报告《进程同步与互斥》实验的主要目的是掌握基本的进程同步与互斥算法,了解生产者-消费者问题,并学习使用 Windows 2000/XP 中基本的同步对象,掌握相关 API 的使用方法。实验中,设计了一个控制台...