进程同步:实验报告

合集下载
  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

#include

#include

#include

#include #include 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);// 生产一个产品,并放入缓冲区,产品数量 +1

printf("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); // 消费一个产品,缓冲区大小 +1

printf("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 的 顺序显示;如:

A

B

C

A

B

第一步:分析

源程序输出结果依次是十个 A ,十个 B ,十个 C ,而我们要求的是输出 A 、B 、C ,A 按顺 序输出,因此可以看出有同步关系, 即一前一后的行为, 存在多种同步机制,就可以引入前 趋图的原理来解决,使源程序输出变成要求所示

前驱的概念: 1.要为每一对前驱关系各设置一个同步变量; 2.在“前操作”之后对相应

的同步变量执行 V 操作; 3 在“后操作”之前对应的同步变量执行 P 操作

第三步:根据上图以及分析,写出修改代码,使代码输出如要求所示

#include

#include

#include

#include

#include

//执行消费者线程

相关文档
最新文档