操作系统实验四 进程同步与互斥

一、实验目的:

  1. 掌握基本的同步与互斥算法,理解P,V操作。
  2. 理解生产者消费者模型,了解其它典型的同步互斥模型,如哲学家就餐、读者-写者模型等。
  3. 了解LINUX中进程同步互斥的实现方法,掌握相关函数的使用方法。
  4. 学习使用Windows中基本的同步对象,掌握相关API的使用方法。

了解Windows中多线程的并发执行机制,实现进程的同步与互斥。

二、实验环境:

一台运行Linux操作系统的计算机。

  • 实验内容:

PART 1 LINUX环境

1. 生产者-消费者问题

(1)以下给出生产者-消费者问题的基本框架,未实现同步互斥控制,仔细查看程序运行结果,分析原因。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include <semaphore.h>

#include <time.h>

#define N 4   // 消费者或者生产者的数目

#define M 20 // 缓冲数目

int in = 0;   // 生产者放置产品的位置

int out = 0; // 消费者取产品的位置

char buff[M]; // 缓冲区

int producter_id = 0;   //生产者id

int consumer_id = 0; //消费者id

/* 打印缓冲情况 */

void print()

{

int i;

for(i = 0; i < M; i++)

   printf("%c ", buff[i]);

printf("\n");

}

/* 生产者方法 */

void *producter()

{

int id = ++producter_id;

while(1)

{

   // 用sleep的数量可以调节生产和消费的速度

   sleep(2);

   char data;

   data=rand()%26+65;     

   in = in % M;

   printf("生产者进程%d在%2d位置产生数据%c: ", id,in,data);  

   buff[in] = data;  

   print();  

   ++in;

}

}

/* 消费者方法 */

void *consumer()

{

char data;

int id = ++consumer_id;

while(1)

{

   // 用sleep的数量可以调节生产和消费的速度

   sleep(1);

   out = out % M;

   data=buff[out];

   printf("消费者进程%d在%2d位置消费数据%c: ",id, out,data);   

   buff[out] = '*';

   print();

   ++out;

}

}

int main()

{

pthread_t p[N];

pthread_t c[N];

int i;

int ret[N];

for(i=0; i<M; i++)

   buff[i]='*';  //'*'表示空,初始化缓冲区

srand((int)time(NULL));

// 创建N个生产者线程

for (i = 0; i < N; i++)

{

   ret[i] = pthread_create(&p[i], NULL,(void*)producter, (void *)(&i));

   if(ret[i] != 0)

   {

    printf("producter %d creation failed \n", i);

    exit(1);

   }

}

//创建N个消费者线程

for(i = 0; i < N; i++)

{

   ret[i] = pthread_create(&c[i], NULL, (void*)consumer, NULL);

   if(ret[i] != 0)

   {

    printf("consumer %d creation failed\n", i);

    exit(1);

   }

}

//销毁线程

for(i = 0; i < N; i++)

{

   pthread_join(p[i],NULL);

   pthread_join(c[i],NULL);

}

exit(0);

}

(2) 在代码中加入同步互斥控制功能,使程序能够实现生产者-消费者问题。

实现方法参考教材109页算法,提示:

使用两个同步信号量,sem_t empty_sem; // 同步信号量, 当满了时阻止生产者放产品

sem_t full_sem;   // 同步信号量, 当没产品时阻止消费者消费

使用一个互斥信号量,pthread_mutex_t mutex; // 互斥信号量, 一次只有一个线程访问缓冲

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include <semaphore.h>

#include <time.h>

#define N 4   // 消费者或者生产者的数目

#define M 20 // 缓冲数目

int in = 0;   // 生产者放置产品的位置

int out = 0; // 消费者取产品的位置

char buff[M]; // 缓冲区

int producter_id = 0;   //生产者id

int consumer_id = 0; //消费者id

sem_t empty_sem;// 同步信号量, 当满了时阻止生产者放产品

sem_t full_sem;// 同步信号量, 当没产品时阻止消费者消费

pthread_mutex_t mutex;

/* 打印缓冲情况 */

void print()

{

int i;

for(i = 0; i < M; i++)

   printf("%c ", buff[i]);

printf("\n");

}

/* 生产者方法 */

void *producter()

{

int id = ++producter_id;

while(1)

{

   // 用sleep的数量可以调节生产和消费的速度

   sleep(2);

   char data;

   data=rand()%26+65;     

   in = in % M;

   printf("生产者进程%d在%2d位置产生数据%c: ", id,in,data);  

   buff[in] = data;  

   print();  

   ++in;

}

}

/* 消费者方法 */

void *consumer()

{

char data;

int id = ++consumer_id;

while(1)

{

   // 用sleep的数量可以调节生产和消费的速度

   sleep(1);

   out = out % M;

   data=buff[out];

   printf("消费者进程%d在%2d位置消费数据%c: ",id, out,data);   

   buff[out] = '*';

   print();

   ++out;

}

}

int main()

{

pthread_t p[N];

pthread_t c[N];

int i;

int ret[N];

for(i=0; i<M; i++)

   buff[i]='*';  //'

  • 14
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊可可茶+

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值