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

操作系统课设

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 资源是通过一组系统调用实现的。任务二中将使用 IPC 中提供的 semget(),semop (),及 semctl()等信号量系统调用,它们的简介请查询实验四的背景知识部分,具体如何使用请自行进一步查询有关资料。

4、实验内容和要求

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

5、描述

emmmmm,因为这道题的代码如果看其他大佬的博客实在是不好改,所以我和老师说,我想写写者优先,老师表很赞同(233333),所以我的代码是写者优先。总的来说,写者优先和读者优先其实差不多,主要是要理解信号量是如何控制进程之间的同步以及进程内的互斥,这些其实都不算很难,加油叭,后来者。
6、代码

#include<windows.h>
#include <iostream>
#include<stdio.h>

#define MAX_READER_NUM 512
#define READER_NUM 2
#define WRITER_NUM 3
#define MOD 100

using namespace std;

int readcount=0;
int writecount=0;
HANDLE a;//写着优先读者的第1个互斥量
HANDLE b;//写着优先读者的第2个互斥量,同时也是写者让读者阻塞的信号量
HANDLE c;//写着优先读者的第3个互斥量
HANDLE y;//这个可以参考书上的伪代码理解
HANDLE middle;//实现读者写者互斥的信号量
HANDLE input;//这是将输出作为临界资源,这样有利于防止两个进程同时输出,造成本应该换行的输出在一行输出,此外这是读者的输出,命名不规范
HANDLE output;//同Input,这是写者的输出
DWORD WINAPI reader(LPVOID);//调用windowsAPI函数
DWORD WINAPI writer(LPVOID);
bool p_continue=true;
int test=0;
int process_write_num=0;//统计每个进程执行的次数
int process_read_num=0;

int main()
{
    a = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
    b = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
    c = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
    input = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
    output=CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
    middle = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
    y=CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);
    HANDLE hThreads[READER_NUM + WRITER_NUM];
    DWORD readerID[READER_NUM];
    DWORD writerID[WRITER_NUM];
    for(int i=0;i<WRITER_NUM;i++)
    {
        hThreads[i]=CreateThread(NULL,0,writer,NULL,0,&writerID[i]);//创建写者进程
        if(hThreads[i]==NULL)
            return -1;
    }
    for(int i=0;i<READER_NUM;i++)
    {
        hThreads[i]=CreateThread(NULL,0,reader,NULL,0,&readerID[i]);//创建读者线程
        if(hThreads[i]==NULL)
            return -1;
    }
    while(p_continue)//当输入空格的时候结束程序
    {
        if(getchar())
        {
            p_continue = false;
            printf("在这个过程中读者进程的数量:%d\n",process_read_num);
            printf("在这个过程中写者进程的数量:%d\n",process_write_num);
        }
    }
    return 0;
}

void READUNIT()
{
    WaitForSingleObject(input,INFINITE);//p操作
    process_read_num++;
    cout<<"一个读者进程开始读:";
    cout<<test<<endl;
    ReleaseSemaphore(input,1,NULL);//v操作
}

void WRITEUNIT()
{
    process_write_num++;
    cout<<"一个写者开始写:";
    test=(test+1)%MOD;
    cout<<test<<endl;
    ReleaseSemaphore(output,1,NULL);
}

DWORD WINAPI writer(LPVOID lpPara)
{
    while(p_continue)
    {
        WaitForSingleObject(y,INFINITE);
        writecount++;
        if(writecount==1)
            WaitForSingleObject(b,INFINITE);
        ReleaseSemaphore(y,1,NULL);
        WaitForSingleObject(middle,INFINITE);
        WRITEUNIT();
        ReleaseSemaphore(middle,1,NULL);
        WaitForSingleObject(y,INFINITE);
        writecount--;
        if(writecount==0)
            ReleaseSemaphore(b,1,NULL);
        ReleaseSemaphore(y,1,NULL);
        Sleep(300);
    }
    return 0;
}

DWORD WINAPI reader(LPVOID lpParar)
{
    while(p_continue)
    {
        WaitForSingleObject(a,INFINITE);
        WaitForSingleObject(b,INFINITE);
        WaitForSingleObject(c,INFINITE);
        readcount++;
        if(readcount==1)
            WaitForSingleObject(middle,INFINITE);
        ReleaseSemaphore(a,1,NULL);
        ReleaseSemaphore(b,1,NULL);
        ReleaseSemaphore(c,1,NULL);
        READUNIT();
        WaitForSingleObject(c,INFINITE);
        readcount--;
        if(readcount==0)
            ReleaseSemaphore(middle,1,NULL);
        ReleaseSemaphore(c,1,NULL);
        Sleep(200);
    }
    return 0;
}

总的来说的话,emmmmm,还是看别人的看的太多了,几乎是模拟别人写的代码,23333,但是课设嘛,总有很多不会的,不建议大家抄,但是可以在别人的基础上做更新(当然不是简单的更换输出和变量名,23333),好啦,就到这叭,代码看不懂的地方可以在下方留言哈。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值