进程同步:实验报告

合集下载

操作系统 实验三 进程同步

操作系统 实验三 进程同步

集美大学计算机工程学院实验报告课程名称:操作系统指导教师:王丰实验成绩:实验编号:实验三实验名称:进程同步班级:计算12姓名:学号:上机实践日期:2015.5上机实践时间:2学时一、实验目的1、掌握用Linux信号灯集机制实现两个进程间的同步问题。

2、共享函数库的创建二、实验环境Ubuntu-VMware、Linux三、实验内容⏹需要的信号灯: System V信号灯实现☐用于控制司机是否可以启动车辆的的信号灯 S1=0☐用于控制售票员是否可以开门的信号灯 S2=0System V信号灯实现说明□ System V的信号灯机制属于信号灯集的形式, 一次可以申请多个信号灯.□同样利用ftok()生成一个key: semkey=ftok(path,45);□利用key申请一个包含有两个信号灯的信号灯集, 获得该集的idsemid=semget(semkey,2,IPC_CREAT | 0666);□定义一个联合的数据类型union semun{int val;struct semid_ds *buf;ushort *array;};□利用semctl()函数对信号灯初始化,参数有:信号灯集的id: semid要初始化的信号灯的编号:sn要设定的初始值:valvoid seminit(int semid, int val,int sn){union semun arg;arg.val=val;semctl(semid,sn,SETVAL,arg);}利用初始化函数,初始化信号灯:seminit(semid,0,0);//用来司机启动汽车的同步seminit(semid,0,1);//用来售票员开门的同步控制□利用semop()函数, 对信号灯实现V操作:sembuf是一个在头部文件中的预定义结构、semid—信号灯集id, sn—要操作的信号灯编号void semdown(int semid,int sn){/* define P operating*/struct sembuf op;op.sem_num=sn;op.sem_op=-1;//P操作为-1op.sem_flg=0;semop(semid,&op,1);}2、Linux的静态和共享函数库·Linux生成目标代码: gcc -c 源程序文件名(将生成一个与源程序同名的.o目标代码文件。

进程的同步与互斥实验报告

进程的同步与互斥实验报告

进程的同步与互斥实验报告1.实验目的进程(线程)的同步与互斥是操作系统中非常重要的概念,本实验旨在通过实际操作,加深对这些概念的理解和掌握。

通过编写多个进程(线程),并在其间进行同步与互斥操作,验证同步与互斥的实际效果。

2.实验环境本实验在Linux系统下进行,使用C/C++语言编程。

3.实验内容3.1同步在实验中,我们编写了两个进程A和B,这两个进程需要按照特定的顺序执行。

为了实现同步,我们使用信号量机制来确保进程A和B按照正确的顺序执行。

3.2互斥在实验中,我们编写了多个进程C和D,这些进程需要同时对一个共享资源进行访问。

为了实现互斥,我们使用互斥锁机制来确保同一时刻只有一个进程访问共享资源。

4.实验过程4.1同步实验编写进程A和进程B的代码,使用信号量机制实现同步。

进程A先运行,然后通过信号量唤醒进程B,进程B再开始执行。

通过观察进程的运行顺序,验证同步机制是否起作用。

4.2互斥实验编写进程C和进程D的代码,使用互斥锁机制实现互斥。

进程C和进程D同时对一个共享资源进行访问,通过互斥锁来确保同一时刻只有一个进程访问共享资源。

观察进程的输出结果,验证互斥机制是否起作用。

5.实验结果5.1同步实验结果进程A开始执行进程A执行完毕进程B开始执行进程B执行完毕5.2互斥实验结果进程C开始执行进程C访问共享资源进程C执行完毕进程D开始执行进程D访问共享资源进程D执行完毕6.实验分析通过上述结果可以看出,同步实验中进程A和进程B按照正确的顺序执行,证明了同步机制的有效性。

互斥实验中进程C和进程D能够正确地交替访问共享资源,证明了互斥机制的有效性。

7.实验总结通过本次实验,我深刻理解了进程(线程)的同步与互斥,并通过实际操作加深了对这些概念的理解。

同步和互斥是操作系统中非常重要的概念,对于应对资源竞争和提高程序性能具有重要意义。

在实际开发中,我们应该合理使用同步和互斥机制,以确保程序的正确性和并发执行的效率。

进程同步实验报告

进程同步实验报告

一、实验目的1. 理解进程同步的概念和原理;2. 掌握进程同步的基本方法和机制;3. 学会使用信号量实现进程同步;4. 通过实验验证进程同步机制的有效性。

二、实验原理1. 进程同步:在多道程序设计中,进程的执行是并发的,但某些情况下需要保证多个进程按照一定的顺序执行,以避免出现数据不一致、死锁等问题。

进程同步是指通过某种机制,协调多个进程的执行顺序,保证它们能够正确、有效地共享资源。

2. 信号量:信号量是一种特殊的变量,用于实现进程同步。

信号量具有两个原子操作:P操作(wait)和V操作(signal)。

P操作用于申请资源,V操作用于释放资源。

3. 互斥锁:互斥锁是一种常见的进程同步机制,用于保证临界资源的互斥访问。

当一个进程进入临界区时,它会尝试获取互斥锁,如果锁已被其他进程获取,则该进程进入等待状态;当进程退出临界区时,它会释放互斥锁。

三、实验内容1. 实验环境:Linux操作系统,C语言编程环境。

2. 实验工具:gcc编译器、gdb调试器。

3. 实验步骤:(1)创建一个互斥锁,用于保护临界资源。

(2)编写两个进程,分别模拟对临界资源的访问。

(3)在进程访问临界资源前,使用P操作尝试获取互斥锁。

(4)在进程访问临界资源后,使用V操作释放互斥锁。

(5)编译并运行程序,观察进程执行情况。

四、实验结果与分析1. 实验结果:(1)在互斥锁的保护下,两个进程能够按照预期顺序访问临界资源。

(2)当其中一个进程正在访问临界资源时,另一个进程会进入等待状态。

(3)当进程访问临界资源完成后,它会释放互斥锁,允许其他进程访问。

2. 实验分析:(1)互斥锁能够有效地保护临界资源,避免数据不一致问题。

(2)信号量P操作和V操作保证了进程的同步,避免了死锁现象。

(3)通过实验验证了进程同步机制的有效性。

五、实验总结本次实验通过使用信号量和互斥锁,实现了进程同步。

实验结果表明,信号量和互斥锁能够有效地保证进程按照预期顺序执行,避免数据不一致和死锁等问题。

操作系统实验3进程同步报告

操作系统实验3进程同步报告

实验三进程同步一、实验目的:1.了解进程和线程的同步方法,学会运用进程和线程同步方法来解决实际问题;2.了解windows系统下Win32 API或Pthread信号量机制的使用方法;二、实验预备内容:1.对书上所说基于信号量的有限缓冲的生产者-消费者问题;2.对于信号量的概念有大概的了解,知道如何用信号量的wiat()和signal()函数如何取消应用程序进入临界区的忙等;三、实验环境说明:此实验在Win7(32位) CodeBlocks环境下实现,采用WinAPI的信号量机制。

四、实验内容:设计一个程序解决有限缓冲问题,其中的生产者与消费者进程如下图所示。

在Bounded-Buffer Problem(6.6.1节)中使用了三个信号量:empty (记录有多少空位)、full(记录有多少满位)以及mutex(二进制信号量或互斥信号量,以保护对缓冲区插入与删除的操作)。

对于本项目,empty和full将采用标准计数信号量,而mutex将采用二进制信号量。

生产者与消费者作为独立线程,在empty、full、mutex的同步前提下,对缓冲区进行插入与删除。

本项目可采用Pthread或Win32 API。

(本实验采用Win32 API)五、程序设计说明:1.全局变量:定义缓冲区数组及其环形队列表达方式,定义mutex、empty、full 三个信号量。

empty记录缓冲区有多少个空位;full记录缓冲区有多少个满位;mutex作为互斥信号量,保护对缓冲区插入或删除的操作。

具体定义如下:定义生产者、消费者线程结构和包含的信息:(由于题目中没有要求,因此只定义了编号一个变量)2.缓冲区:缓冲区是一个元数据类型为buffer_item(可通过typedef定义)的固定大小的数组,按环形队列处理。

buffer_item的定义及缓冲区大小可保存在头文件中:A.insert_item():先判断缓冲区是否已满,不满则向缓冲区中插入元素;B.remove_item()先判断缓冲区是否为空,不空则从缓冲区中删除元素;3.生产者线程:生产者线程交替执行如下两个阶段:睡眠一段随机事件,向缓冲中插入一个随机数。

北邮操作系统进程同步实验报告与源代码

北邮操作系统进程同步实验报告与源代码

北邮操作系统进程同步实验报告与源代码进程管理实验报告1.实验目的:(1)理解进程/线程同步的方法,学会运用进程/线程同步的方法解决实际问题;(2)了解windows系统或unix/linux系统下中信号量的使用方法。

2.实验内容编写一个有关生产者和消费者的程序:每个生产者每次生产一个产品存入仓库,每个消费者每次从仓库中取出一个产品进行消费,仓库大小有限,每次只能有一个生产者或消费者访问仓库。

要求:采用信号量机制。

3、环境说明本实验是在win7环境下使用dev编译器实现的,采用Win API的信号量机制。

4、程序设计说明该程序根据教材中的消费者生产者问题编写的,使用了教材中提供的框架思路以及库函数,使用CreateThread建立新的线程,使用CreateMutex 创建一个互斥信号量,使用CreateSemaphore创建信号量,使用ReleaseMutex释放线程的互斥信号量,使用ReleaseSemaphore对指定的信号量增加指定的值,使用WaitForSingleObject等待空位,使用CloseHandle在操作结束后关闭线程和信号量。

在这个程序里我设计了三个函数:Int main()是主函数,其中包含了缓冲区大小的设置,生产者消费者发出请求等内容以及线程创建等内容DWORD WINAPI producer(LPVOID lpPara)是生产者等待缓冲区的使用权并对缓冲区进行操作DWORD WINAPI consumer(LPVOID lpPara)是消费者等待缓冲区的使用权并对缓冲区进行操作该程序模拟生产者消费者问题,首先要设置缓冲区的大小,输入请求资源的各个进程的信息以及请求时间,并且按照请求时间对各进程进行排序,创建线程,然后按序依次对缓冲区进行操作,详细设计见源代码。

5、程序运行结果截图:只有生产者请求,没有消费者请求,请求满足只有消费者请求,没有生产者请求,消费者的请求不成功:生产者请求大于消费者请求并且消费者请求在生产者放入产品之后:消费者请求多于生产者请求,只能满足部分消费者请求,不能满足全部:6、源代码:#include#include#include#include#include#includeusing namespace std;#define MAX_BUF 1000#define MAX_REQ 20HANDLE mutex;HANDLE full;HANDLE empty;HANDLE thread[MAX_REQ]; DWORD pro_id[MAX_REQ]; DWORD con_id[MAX_REQ]; struct request{int type;//记录生产者消费者的类型int seq; //记录请求次序}req[MAX_REQ];int buf_size;int req_size;int no;int buffer[MAX_BUF];int in;int out;int result;bool cmp(request a,request b){ return a.seqDWORD WINAPI producer(LPVOID lpPara){WaitForSingleObject(full,INFINITE);WaitForSingleObject(mutex,INFINITE);printf("生产者%d将第%d号产品放入缓冲区……\n",(int)lpPara,no);buffer[in]=no++;in=(in+1)%buf_size;printf("成功放入缓冲区!\n\n",(int)lpPara);ReleaseMutex(mutex);ReleaseSemaphore(empty,1,NULL);return 0;}DWORD WINAPI consumer(LPVOID lpPara){WaitForSingleObject(empty,INFINITE);WaitForSingleObject(mutex,INFINITE);printf("消费者%d将第%d号产品从缓冲区取出……\n",(int)lpPara,buffer[out]);buffer[out]=0;printf("成功从缓冲区取出!\n\n",(int)lpPara);ReleaseMutex(mutex);out=(out+1)%buf_size;ReleaseSemaphore(full,1,NULL);return 0;}int main(){int i;int p=0;no = 1;in=out=0;memset(buffer, 0, sizeof(buffer));printf("请设置缓冲区大小:");scanf("%d",&buf_size);printf("请输入请求使用资源进程的个数:");scanf("%d",&req_size);for(i=0;iprintf("请选择是消费者进程(0)还是生产者进程(1):");scanf("%d",&req[i].type);printf("请输入该进程的请求时间:");scanf("%d",&req[i].seq);}sort(req,req+req_size,cmp);mutex=CreateMutex(NULL,FALSE,NULL);full=CreateSemaphore(NULL,buf_size,buf_size,NULL);empty=CreateSemaphore(NULL,0,buf_size,NULL);for(i=0;i{if(req[i].type==0){thread[i]=CreateThread(NULL, 0, consumer, (LPVOID)i, 0, &con_id[i]); if(thread[i]==NULL)return -1;printf("\n消费者请求从缓冲区中取产品,请求时间为%d\n",req[i].seq);}if(req[i].type==1){thread[i]=CreateThread(NULL,0,producer,(LPVOID)i,0,&pro_id[i]);if(thread[i]==NULL)return -1;printf("\n生产者请求往缓冲区中放产品,请求时间为%d\n",req[i].seq);}}result = WaitForMultipleObjects(req_size, thread, TRUE, 500);if (result == WAIT_TIMEOUT)printf("\n请求不能被完全满足\n");elseprintf("\n能够满足所有请求\n");for(int i=0; iCloseHandle(thread[i]);CloseHandle(mutex);CloseHandle(full);CloseHandle(empty);system("pause");return 0;}7、实验总结:本次实验基于书上的生产者消费者问题,原理在上课的时候老师已经详细地讲解过,但是在具体编程实现的过程中也遇到了很多问题,除了书上的库函数之外还有一些函数书上并没有给出用法,比如如何创建线程等函数,通过查阅参考相关资料解决,通过编写代码也系统地理解了生产者消费者问题的操作过程,线程的创建,信号量的创建以及信号量的使用方法等情况,遇到的好多编代码上的细节问题通过反复调试解决,有较大收获。

进程同步实验报告

进程同步实验报告

中北大学软件学院实验报告专 业: 软件工程方 向: 软件开发与测试课程名称: 操作系统班 级:学 号:姓 名:辅导教师:2017年9月制成绩:实验时间2017年11月5日8时至10时学时数22学时1.实验名称进程同步2.实验内容编程实现生产者-消费者问题的模拟。

3.基本要求1.生产者消费者对缓冲区进行互斥操作。

2. 缓冲区大小为10,缓冲区满则不允许生产者生产数据,缓冲区空则不允许消费者消费数据。

3. 生产者消费者各循环操作10次。

4. 实验原理或流程图生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。

在同一个进程地址空间内执行的两个线程。

生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

消费者线程从缓冲区中获得物品,然后释放缓冲区。

当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。

当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

5.源程序#i n c l u d e<s t d i o.h>#i n c l u d e<p t h r e a d.h>#i n c l u d e<s e m a p h o r e.h>#i n c l u d e<u n i s t d.h>v o i d*p r o d u c t e r_f(v o i d*a r g);v o i d*c o n s u m e r_f(v o i d*a r g);s e m_t e m p t y;//信号量e m p t ys e m_t f u l l;//信号量f u l li n t r u n n i n g=1;i n t a p p l e_n u m=0;i n t m a i n(v o i d){p t h r e a d_t c o n s u m e r_t;//消费者p t h r e a d_t p r o d u c t e r_t;//生产者//p s h a r e d表示信号量共享类型, 为0时,表示只能在当前进程的//多个线程之间共享,不为0时,是可以和其他进程间共享该信号量//使用信号量,用来协作生产者和消费者的顺序,即实现同步效果s e m_i n i t(&e m p t y,0,1);//初始化e m p t y信号量s e m_i n i t(&f u l l,0,0);//初始化f u l l信号量p t h r e a d_c r e a t e(&c o n s u m e r_t,N U L L,c o n s u m e r_f,(v o i d*)&r u n n i n g); //创建消费者线程p t h r e a d_c r e a t e(&p r o d u c t e r_t,N U L L,p r o d u c t e r_f,(v o i d*)&r u n n i n g);//创建生产者线程//s l e e p(1);//睡眠3秒u s l e e p(1000);//睡眠10微秒r u n n i n g=0;p t h r e a d_j o i n(c o n s u m e r_t,N U L L);p t h r e a d_j o i n(p r o d u c t e r_t,N U L L);s e m_d e s t r o y(&e m p t y);s e m_d e s t r o y(&f u l l);r e t u r n0;}v o i d*p r o d u c t e r_f(v o i d*a r g){w h i l e(*(i n t*)a r g){s e m_w a i t(&e m p t y);a p p l e_n u m++;p r i n t f("p r o d u c t e r生产第%d个香蕉\n",a p p l e_n u m);s e m_p o s t(&f u l l);u s l e e p(1);}}v o i d*c o n s u m e r_f(v o i d*a r g){w h i l e(*(i n t*)a r g){s e m_w a i t(&f u l l);p r i n t f("c o n s u m e r消费第%d个香蕉\n",a p p l e_n u m);s e m_p o s t(&e m p t y);u s l e e p(1);}}6.运行截图7.实验心得本次实验学习了进程的同步问题,进程是计算机操作系统重要的一个功能,学好进程才能学好其他。

山东大学操作系统实验报告4进程同步实验

山东大学操作系统实验报告4进程同步实验

计算机科学与技术学院实验报告int msq_id;if((msq_id = get_ipc_id("/proc/sysvipc/msg",msq_h)) < 0 ) { if((msq_id = msgget(msq_h,msq_flg)) < 0){perror("messageQueue set error");exit(EXIT_FAILURE);}}return msq_id;}实验结果:分析:多进程的系统中避免不了进程间的相互关系。

进程互斥是进程之间发生的一种间接性作用,一般是程序不希望的。

通常的情况是两个或两个以上的进程需要同时访问某个共享变量。

我们一般将发生能够问共享变量的程序段称为临界区。

两个进程不能同时进入临界区,否则就会导致数据的不一致,产生与时间有关的错误。

解决互斥问题应该满足互斥和公平两个原则,即任意时刻只能允许一个进程处于同一共享变量的临界区,而且不能让任一进程无限期地等待。

进程同步是进程之间直接的相互作用,是合作进程间有意识的行为,典型的例子是公共汽车上司机与售票员的合作。

只有当售票员关门之后司机才能启动车辆,只有司机停车之后售票员才能开车门。

司机和售票员的行动需要一定的协调。

同样地,两个进程之间有时也有这样的依赖关系,因此我们也要有一定的同步机制保证它们的执行次序。

信号量机制就是其中的一种。

信号灯机制即利用pv操作来对信号量进行处理。

PV操作由P操作原语和V 操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的值减1,即S=S-1;②如果S³0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。

V(S):①将信号量S的值加1,即S=S+1;②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。

PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。

进程同步:实验报告

进程同步:实验报告

1.实验内容(进程的同步)(1)阅读理解示例程序。

(2)说明示例程序是否能适合解决N个生产者和1个消费者问题,并设计实验验证(3) 参照教材修改为N个生产者和1个消费者问题(4) 思考N个生产者和M个消费者问题的解决方案(不要求)(5) 利用信号量解决同步问题。

2.实验目的通过程序模拟及验证生产者消费者问题等经典问题,深入理解并发中的同步和互斥的概念3.实验原理(1)进程概念:(1.定义:程序的一次执行过程(2.三种基本状态:就绪状态,执行状态,阻塞状态(2)进程同步:(1.定义:并发进程在执行次序上的协调,以达到有效的资源共享和相互合作,使程序执行有可再现性。

(2.两种形式的制约关系:(一:资源共享关系:进程间接制约,需互斥地访问临界资源。

)、(二:相互合作关系:进程直接制约)(3.临界资源:一次仅允许一个进程访问的资源,引起不可再现性是因为临界资源没有互斥访问。

(3)信号量:定义一个用于表示资源数目的整型量S,它与一般的整型量不同,除初始化外,仅能通过两个标准的原子操作wait(S)和signal(S)来访问,俗称P,V操作。

通俗来讲就是用P来访问资源后减去一个单位资源,用V操作来释放一个单位资源就是现有资源上加一个单位资源。

4.实验内容一:说明示例程序是否能适合解决N个生产者和1个消费者问题,并设计实验验证答:示例程序不能解决多个生产者和消费者的问题,它是解决单个消费者和生产者的。

如果可以就要修改代码,如“二”所说。

二:多个消费者和生产者的问题如上图所示:如果要解决多个生产者和消费者的问题:第一步:分析上图得出了两种关系,分别是异步和同步的关系第二步:异步关系的是生产者和生产者之间的,因为同一时刻只能有一个生产者访问缓冲区,所以我们就可以设置临界资源.获得临界资源的生产者才能把产品放到缓冲区里第三步:同步关系有两个,首先是生产者和缓冲区之间,再是缓冲区和消费者之间。

他们都满足一前一后的关系,即当缓冲区空间未满时,生产者才可以放产品;缓冲区不为空的时候才可以让消费者取出产品消费。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.实验内容(进程的同步)(1) 阅读理解示例程序。

(2) 说明示例程序是否能适合解决 N 个生产者和 1 个消费者问题,并设计实验验证(3) 参照教材修改为 N 个生产者和 1 个消费者问题(4) 思考 N 个生产者和 M 个消费者问题的解决方案(不要求)(5) 利用信号量解决同步问题。

2.实验目的通过程序模拟及验证生产者消费者问题等经典问题,深入理解并发中的同步和互斥的概念3.实验原理(1)进程概念:(1.定义:程序的一次执行过程( 2.三种基本状态 :就绪状态,执行状态,阻塞状态(2)进程同步:(1.定义:并发进程在执行次序上的协调,以达到有效的资源共享和相互合作,使程序执行有可再现性。

( 2.两种形式的制约关系: (一:资源共享关系:进程间接制约,需互斥地访问临界资源。

)、(二:相互合作关系:进程直接制约)(3.临界资源:一次仅允许一个进程访问的资源,引起不可再现性是因为临界资源没有互斥访问。

(3)信号量:定义一个用于表示资源数目的整型量S,它与一般的整型量不同,除初始化外,仅能通过两个标准的原子操作 wait(S)和 signal(S)来访问,俗称 P,V操作。

通俗来讲就是用P 来访问资源后减去一个单位资源,用 V 操作来释放一个单位资源就是现有资源上加一个单位资源。

4.实验内容一:说明示例程序是否能适合解决 N 个生产者和 1 个消费者问题,并设计实验验证答:示例程序不能解决多个生产者和消费者的问题,它是解决单个消费者和生产者的。

如果可以就要修改代码,如“二”所说。

二:多个消费者和生产者的问题生产者 1 如上图所示 :如果要解决多个生产者和消费者的问题:第一步:分析上图得出了两种关系,分别是异步和同步的关系 第二步:异步关系的是生产者和生产者之间的, 因为同一时刻只能有一个生产者 访问缓冲区,所以我们就可以设置临界资源 .获得临界资源的生产者才能把产品 放到缓冲区里第三步:同步关系有两个, 首先是生产者和缓冲区之间, 再是缓冲区和消费者之 间。

他们都满足一前一后的关系, 即当缓冲区空间未满时, 生产者才可以放产品; 缓冲区不为空的时候才可以让消费者取出产品消费。

第四步:设计变量,用 C 语言编程,在 linux 上运行,观察结果。

代码如下:#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <unistd.h>#include <sys/types.h> #include <semaphore.h> int n=10;int buffer[10];// 缓冲区空间大小int in=0,out=0; sem_t mutex,empty,full;// 设置临界资源,定义两个同步关系的信号量 void*producer(void *arg){ // 生产者sem_wait(&mutex); // 访问临界资源int tag= pthread_self()%100;int nextPro;srand(time(NULL)+tag);生产者 6缓冲区 消费者生产者 2生产者 3生产者 4 生产者 5相关头文件while(1){nextPro = rand()%97;sem_wait(&empty); // 生产一个产品,并放入缓冲区,缓冲区空间大小-1 buffer[in] = nextPro;in = (in+1)%n;sem_post(&full);// 生产一个产品,并放入缓冲区,产品数量 +1printf("production:%d\n",nextPro);sem_post(&mutex);// 释放临界资源,给其它线程用 usleep(1000*1000/2);}}void* consumer(void *arg) // 消费者int item;while(1){sem_wait(&full);// 消费一个产品,缓冲区产品数量 -1 item = buffer[out];sem_post(&empty); // 消费一个产品,缓冲区大小 +1printf("consume:%d\n",item);out = (out+1)%n; usleep(1000*1000/2);}}int main(int argc, char const *argv[]){pthread_t tid[6]; sem_init( &mutex, 0,1); sem_init( &empty, 0,10);sem_init( &full, 0,0);for(int i=0;i<6;i++){ pthread_create(&tid[i], NULL, producer, NULL);} // 执行生产者线程 //定义 7 个线程//对临界资源和信号量赋初值//pthread_create(&tid[6], NULL, consumer, NULL);for(int i = 0; i < 6 ; i++)pthread_join(tid[i], NULL);return 0;}三:开启 3个线程,这 3个线程分别输出 A 、B 、C 各 10遍,要求输出结果必须按 ABC 的 顺序显示;如:ABCAB第一步:分析源程序输出结果依次是十个 A ,十个 B ,十个 C ,而我们要求的是输出 A 、B 、C ,A 按顺 序输出,因此可以看出有同步关系, 即一前一后的行为, 存在多种同步机制,就可以引入前 趋图的原理来解决,使源程序输出变成要求所示前驱的概念: 1.要为每一对前驱关系各设置一个同步变量; 2.在“前操作”之后对相应的同步变量执行 V 操作; 3 在“后操作”之前对应的同步变量执行 P 操作第三步:根据上图以及分析,写出修改代码,使代码输出如要求所示#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <unistd.h>#include <sys/types.h>//执行消费者线程#include <semaphore.h>sem_t a,b,c; //设置整型信号量void* p1(void *arg){// 线程输出 A for(inti=0;i<10;i++){ sem_wait(&c);//p - printf("A\n"); sem_post(&a);//v+ //usleep(1);}}void* p2(void *arg){// 线程输出 Bfor(inti=0;i<10;i++){ sem_wait(&a);printf("B\n"); sem_post(&b);//usleep(1);}}void* p3(void *arg){// 线程输出 C for(int i=0;i<10;i++){ sem_wait(&b);//p printf("C\n"); sem_post(&c);//v //usleep(1);}}int main(){sem_init( &a, 0,0);// 设置信号量初值sem_init( &b, 0,0);sem_init( &c, 0,1);// 对信 号量 a 赋初值 pthread_t tid[3];pthread_create(&tid[0], NULL, p1, NULL);pthread_create(&tid[1], NULL, p2, NULL);pthread_create(&tid[2], NULL, p3, NULL); for(int i = 0; i < 3; i++)pthread_join(tid[i], NULL);printf("main is over\n");}5.调试分析1.生产者和消费最开始没理解到什么是同步, 和互斥关系, 用信号量怎么表当把这些概念依次搞懂,然后在看代码就豁然开朗了2.依次输出 A 、B 、C :在做这道题的时候,没理解到前驱关系,以至程序输出结果 不对,或者就是没有输出。

最后仔细思考,发现输出 A 、B 、C 是一个循环,因该给信 号量 a 赋初值 1,才可以解决。

为了使输出程序的结果更稳定,可以在三个线程中加入 睡眠 sleep();增加响应时间。

6.测试预期结果 实际结果当生产者获得临界资源时, 就放入缓冲区,消费者随机 取出一个产品消费,当缓冲 区满了就只有等消费者消 费,或者缓冲区空了就生产 者生产测试数据 pthread_t tid[6]; // 依次创建7 个线程,其中 tid[0]~[5] 为 生产者吗, tid[6] 为消费者, 缓冲区一共有 11 个单位大 小7.问题回答及知识扩展8. 总结蒋贤武(算法设计 +实验报告撰写) :在消费者和生产者、如何依次输出A 、B 、C 这些问题中,应该理解到什么是进程的同步, 和互斥关系,如何有效的设置信号量。

掌握了这些 之后, 对问题的算法设计就容易了。

在具体解决问题中, 首先要分析问题中的同步,异步有 多少种情况,然后在设置相应的信号量来解决问题附件:sy2.1.c sy2.2.csem_t a,b,c;//设置 信号量,实 现前驱同步关系pthread_t tid[3];// 创建线程, 使输出 A 、B 、C 的代码独立运行sleep (); //加入三个线程,使线程有一定的反映时间当代表 A 、B 、C 的线程运行时,只有获得属于自己的信 号量时才能运行,并输出字 符,否则只能等待。

相关文档
最新文档