操作系统课程设计---实验九 基于信号量机制的并发程序设计

实验九基于信号量机制的并发程序设计

完整课程设计源码及其报告查看陈陈的操作系统课程设计
.
实验九 基于信号量机制的并发程序设计
1、实验目的

(1) 回顾操作系统进程、线程的有关概念,针对经典的同步、互斥、死锁与饥饿问题进行并发

程序设计与实现。

(2) 理解互斥体对象,利用互斥与同步操作编写读者-写者问题的并发程序,加深对 P (即semWait)、V(即 semSignal)原语以及利用 P、V 原语进行进程间同步与互斥操作的理解。

(3) 理解 Linux 支持的信息量机制,利用 IPC 的信号量系统调用编程实现哲学家进餐问题。

2、设计任务:

(1) 读者-写者问题的并发程序设计

(2) 哲学家进餐问题的并发程序设计

以上两个任务任选一个完成即可。

3、背景知识

(1)相关并发控制的 Windows API 函数请参考实验四。

(2)UINX/Linux 系统把信号量、消息队列和共享资源统称为进程间通信资源(IPC resource)。提供给用户的 IPC 资源是通过一组系统调用实现的。Unix/Linux 中可使用 IPC 中提供的 semget(),semop(),及 semctl()等信号量系统调用,它们的简介请查询实验三的背景知识部分,具体如何使用请自行进一步查询有关资料。

4、实验内容和要求

(1) 读者写者问题的并发程序设计

根据实验四中所熟悉的 P、V 原语对应的实际 Windows API 函数,并参考教材中读者-写者问题的算法原理,尝试利用 Windows API 函数实现第一类读者-写者问题(读者优先)。

(2)哲学家进餐问题的并发程序设计

使用 UINX/Linux 系统的系统调用 semget(),semop(),及 semctl()编制一个哲学家进餐问题(教材 P176-177)的程序。思路:为了便于操作和观察结果,用主程序创建一个信号量集(五个叉子信号量),然后先后 fork()五个哲学家子进程,使它们通过对信号量进行 P、V 操作并发地进行 thinking 与 eating.

以上两个实验内容任选一个完成即可。
实验源码:

#include<unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#define ERR_EXIT(m) do{perror(m);exit(EXIT_FAILURE);}while(0)
#define DELAY (rand()%5+1)
union semun 
{
       int              val;    /* Value for SETVAL */
       struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
       unsigned short  *array;  /* Array for GETALL, SETALL */
       struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
};
int semid;//信号量ID
int sem_p(int no)
{
    struct sembuf sb={no,-1,0};
    int ret=semop(semid,&sb,1);
    if(ret==-1)ERR_EXIT("semop");
    return ret;
}
void wait_for_2fork(int no)
{
    int left=no;
    int right=(no+1)%5;//拿右边的筷子
    struct sembuf buf[2]={{left,-1,0},{right,-1,0}};//拿起筷子,因此第left,right信号量减一
    semop(semid,buf,2);//P操作,若果能同时拿起两个筷子,就不用等待
}
void free_2fork(int no)
{
    int left=no;
    int right=(no+1)%5;
    struct sembuf buf[2]={{left,1,0},{right,1,0}};//放下筷子,因此第left,right信号量加一
    semop(semid,buf,2);//V操作,同时放下两只筷子
}
 
int philosephere(int no)
{
   srand(getpid());
   for(;;)
   {
       printf("%d is thinking\n",no);
       sleep(DELAY);
       printf("%d is hungry\n",no);
       wait_for_2fork(no);
       printf("%d is eating\n",no);
       sleep(DELAY);
       free_2fork(no);
   }
}
int main(int argc,char *argv[])
{
    union semun su;
    su.val=1;
    semid=semget(IPC_PRIVATE,5,IPC_CREAT|0666);//因为是父子进程通信,可以设置为IPC_PRIVATE,五个人,因此管理五个信号量
    if(semid==-1)ERR_EXIT("semget");
    for(int i=0;i<5;i++)semctl(semid,i,SETVAL,su); //将5个信号量分别初始化为1
    int no=0;
    int i=0;
    pid_t pid;
    for(i=1;i<5;i++)
    {
        pid=fork();//产生5个进程
        if(pid==-1)ERR_EXIT("fork");
        if(pid==0)
        {
            no=i;
            break;//必须break,否则子进程会创建出新的进程
        }
    }
 // printf("no=%d\n",no);
    philosephere(no);
    return 0;  
}


实验结果截图及其分析:
在这里插入图片描述

更多课程设计源码请进主页查看搜索陈陈不会敲代码

完整课程设计报告请下载陈陈的操作系统课程设计源码及其报告

完整报告包含以下内容的源码以及实验报告:
image-20211209141046247
资源展示如下:
image-20211209111320397
image-20211209111500829
image-20211209111433497

  • 2
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陈陈不会敲代码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值