《操作系统》课程设计 进程/线程通信

一、设计目的与要求

1、掌握操作系统功能模块的设计与实现方法,增强学生的危机感和使命感。
2、能够在阅读和分析开源操作系统的基础上,对其进行功能模块划分;能够指出现有功能模块的不足,并能够通过文献的研究,给出解决方案。
3、能够完成操作系统功能模块的设计、实现与测试,同时在设计操作系统功能模块中,能体现优化和创新意识。
4、能够制定合理的设计与实验方案,针对实验结分析解决过程的影响因素,论证解决方案的合理性,以获得有效结论。
5、能够按照设计的系统组成团队,分工协作,并能承担个体、团队成员以及负责人的角色。
6、能够用口头和书面方式表述设计原理及相关概念与原理,包括陈述发言、清晰表达和回应指令。
7、能够撰写比较规范的课程设计报告。

二、设计内容

利用进程/线程间通信编写程序实现阅览室问题,实现多个读者进程注册、阅读、注销的过程,假设阅览室共有5个座位。
要求:
(1)使用信号量机制和共享存储区机制来实现多个进程/线程之间的通信,同时实现注册与注销的互斥操作。
(2)注册操作要求读者进程填写个人手机或其他身份信息;注销操作要求读者撤销填写的个人信息。

三、设备与环境

1、虚拟机环境:VMware Workstation Pro 16、CentOS 7
2、设备:自己的笔记本电脑

四、设计思想

采用线程通信的方式解决阅览室问题。阅览室问题与生产者消费者问题相类似,进入阅览室相当于生产者进程,离开阅览室相当于消费者进程,设置一个互斥信号量mutex实现对登记表的互斥访问(默认只有一个门进出),初始值为1。设置empty信号量表示空座位的数量,初始值为阅览室座位数5;设置full信号量表示已经就座的座位数,初始值为0。然后分成进入阅览室和离开阅览室两个线程程处理,在主程序中调用pthread.h头文件下的线程创建函数,来进行阅览室的注册注销系统操作,调用进入和离开阅览室线程,利用随机数增加运行结果的随机性。
下面介绍程序中要使用的Linux相关操作函数的应用。信号量semaphore可用于线程同步的锁机制,可以理解为是进阶版的互斥锁。由于互斥锁的粒度较大,如果我们希望在多个线程间对某一对象的部分数据进行共享,使用互斥锁就没有办法实现,只能将整个对象锁住。这样虽然达到了多线程操作共享数据时保证数据正确性的目的,却导致线程的并发性下降。
信号量相当于初始化为N的互斥量,可以允许同时有N个线程来访问公共区域。既能保证同步,数据不混乱,又能提高线程并发。
信号量常见的应用函数有:
sem_init,初始化。
sem_destory,销毁。
sem_wait,加锁,信号量大于0,则信号量–;信号量等于0则线程阻塞。
sem_post,解锁,将信号量++,同时唤醒阻塞在信号量上的线程。
sem_t类型,本质仍是一个结构体,但仍旧在应用期间可以看作一个整数。
信号量不能小于0,需要头文件<semaphore.h>。
由于信号量类型sem_t的实现对用户隐蔽,所以对信号量的++、–操作都只能通过函数来实现,为不能直接++、–信号量,即需要sem_wait()和sem_post();另外,信号量的初值,决定了占用信号量的线程的个数。
信号量不但可以应用在线程间也可以用在进程间,在初始化信号量中sem_init(sem_t *sem, int pshared, unsigned int value);第二个参数就用于决定是在线程间还是在进程间,0用于线程同步,非0进程同步;第三个参数就是N值,用于指定同时访问的线程数。
在pthread.h头文件中,pthread_create是Linux操作系统的创建线程的函数。它的功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。在本程序中我编写了两个线程函数,分别是进入阅览室的函数和离开阅览室的。
pthread_join()函数会一直阻塞调用线程,直到指定的线程终止。当pthread_join()返回之后,应用程序可回收与已终止线程关联的任何数据存储空间。但是,同时需要注意,一定要和上面创建的某一线程配套使用,这样还可以起到互斥的作用。否则多线程可能抢占CPU资源,导致运行结果不确定。

五、主要数据结构和流程

1、定义阅览室座位数。
#define SEAT 5 //定义座位数
2、定义整数型信号量。使用两个信号量,empty表示空座位数量,full表示已就做座位数,当empty值<0时,表示缓冲区已经放满了,读者不能再进入阅览室了。当full值>=0,表示有座位,可以让读者进入阅览室登记。同时定义互斥信号量,实现注册注销的互斥操作。
pthread_mutex_t mutex;
sem_t empty,full;
3、定义全局变量count记录阅览室现有人数。
int count=0;//记录阅览室人数
4、流程
程序首先利用sem_init()函数对empty和full信号量做初始化操作,给empty赋初值5,full初值为0。调用pthread_mutex_init()函数对互斥信号量mutex进行初始化操作,pthread_mutexattr_init()函数成功完成之后会返回零,其他任何返回值都表示出现了错误程序执行时,若等于0,则系统会输出报错信息。然后创建进入阅览室和离开阅览室进程,并借助pthread_join()函数实现对调用线程的阻塞。程序运行结束时要销毁信号量和互斥锁。程序运行流程图如下图1所示。
在这里插入图片描述

六、实验测试结果及结果分析

在虚拟机中打开终端,运行程序。结果如下图2所示。
在这里插入图片描述
从上图的运行结果可以看见,设置了1-1000的随机数作为读者的手机号码,当读者进入阅览室时,登记手机号码,离开时需要注销该手机号码。基本实现了多个线程之间的通信和对注册和注销的互斥操作,以及对阅览室人数的实时统计。

七、课程设计总结

通过实验了解和熟悉了Linux支持的信号量机制和共享存储区机制的基本原理和基本概念。同时Linux提供了一组精心设计的信号量接口来对信号进行操作,它们不只是针对二进制信号量,包含多个操作函数这些函数都是用来对成组的信号量值进行操作的。Linux内核的信号量用来操作系统进程间同步访问共享资源,借助相关的操作函数可以很轻松的实现多个进程或是线程之间的通信。通过对阅览室问题的模拟运行结果,实现了多个进程之间的通信,以及注册与注销的互斥操作,了解到了进程的各种机制以及处理方法。同时此次课设也提升了我自学以及编写报告的能力,更加增添了我对Linux系统编程学习的兴趣。

附件2 源程序清单
readroom1.c

#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<stdio.h>
#include<semaphore.h>
 
#define SEAT 5    //定义座位数

int queue[SEAT];
pthread_mutex_t mutex;   //定义互斥信号量
sem_t empty,full;//定义信号量,使用整形信号量,空座位信号量,已就坐座位信号量
int count=0; //记录阅览室人数
void *intoreadroom(void *arg)
{
     printf("读者进入阅览室...\n");
     int i=0;
     while(1){
    
     sem_wait(&empty);  //p操作 加锁
     pthread_mutex_lock(&mutex);  //互斥锁上锁

    // printf("请输入当前进入阅览室的读者的电话号码:\n");
     //scanf("%d",&queue[i]);
     queue[i]=rand()%1000+1;
     printf("----注册成功!----\n");
     count=count+1;
     printf("手机号码为:%d的读者进入阅览室\n",queue[i]);
     printf("正在读书中...\n");
     
     pthread_mutex_unlock(&mutex);  //互斥锁解锁
     sem_post(&full);  //v操作  解锁
     printf("此时阅览室已有人数为:%d\n",count);
     printf("--------------------------------\n");
     i=(i+1)%SEAT;
     sleep(3);
   }
}
void *leavereadroom(void *arg)
{
   printf("有读者要离开阅览室\n");
   int i=0;
  while(1){
  sem_wait(&full);  //p操作  加锁
  pthread_mutex_lock(&mutex);
  printf("手机号为%d的读者离开阅览室\n",queue[i]);
  queue[i]=0;
  count=count-1;
  printf("----注销成功!----\n");
  pthread_mutex_unlock(&mutex);
  sem_post(&empty);  //v操作 解锁
  printf("此时阅览室剩余空座位个数为:%d\n",count);
  printf("---------------------------------\n");
  i=(i+1)%SEAT;
  sleep(5);
  }
}
 
int main(int argc,char *argv[])
{
      pthread_t pid,cid;
      sem_init(&empty,0,SEAT);  //初始化信号量
      sem_init(&full,0,0);
      int ret=pthread_mutex_init(&mutex,NULL);//初始化线程
      if(ret!=0){
        fprintf(stderr,"mutex init error:%s\n",strerror(ret));
        exit(1);
      }  
      
      pthread_create(&pid,NULL,intoreadroom,NULL);  //两个线程创建
      pthread_create(&cid,NULL,leavereadroom,NULL);
      pthread_join(pid,NULL); //回收
      pthread_join(cid,NULL);
      sem_destroy(&empty);  //销毁信号量
      sem_destroy(&full); 
      pthread_mutex_destroy(&mutex);//销毁互斥锁
      return 0;
}
  • 16
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 武汉理工大学操作系统课程设计使用Java编程语言开展。在该课程设计中,学生将通过自主设计和实现一个操作系统的核心功能,来加深对操作系统原理的理解和应用。 针对操作系统的主要功能模块,学生将会学习与实践相关的Java知识和技术,包括多线程编程、进程管理、内存管理、文件系统实现等。通过使用Java语言进行实现,学生可以更加灵活地运用面向对象的编程思想和Java提供的丰富工具和类库,使得操作系统的设计更加模块化、可扩展和可维护。 在操作系统课程设计中,学生将会面临各种挑战和难题。例如,他们需要设计合适的线程调度算法来实现多任务处理的高效性;需要管理和分配内存空间,避免内存泄漏和碎片问题;需要设计和实现文件系统,支持文件的创建、读写和删除等操作。 通过操作系统课程设计,学生可以提高自己的编程能力和操作系统的理论知识。他们可以学习如何分析和解决复杂的问题,了解操作系统的底层工作原理,加深对计算机系统的理解。 总之,武汉理工大学操作系统课程设计使用Java开展,通过学生的自主设计和实现,以及对Java编程技术的应用,旨在提高学生对操作系统原理的理解和应用能力,培养他们的编程能力和解决问题的能力。这将为他们今后的学习和工作打下坚实的基础。 ### 回答2: 武汉理工大学操作系统课程设计中选择使用Java编写项目是因为Java是一种跨平台编程语言,具有良好的可移植性和兼容性。由于操作系统涉及底层资源的管理和调度,对于编程语言的要求较高,而Java具有面向对象的设计思想,能够较好地结合操作系统的需求进行编程设计。 在操作系统课程设计中,Java可以很好地支持多线程进程调度的实现。多线程操作系统中常用的技术,能够提高程序的并发性和响应速度。通过Java提供的线程库,可以方便地创建和管理多个线程,并实现线程间的同步和通信,从而使程序的并发执行能力得到提升。 此外,Java还具有良好的异常处理机制,能够有效地处理操作系统中可能出现的各种错误和异常情况。操作系统中往往存在各种类型的资源冲突和竞争,因此对于错误处理和异常处理的能力要求较高。Java的异常处理机制能够帮助开发者更好地应对这些问题,并提供相应的错误提示和处理方式。 此外,Java还具有较为完善的标准库和第三方库,为操作系统课程设计提供了丰富的开发资源和工具。可以利用Java的网络编程库,实现操作系统之间的通信和数据交换。同时,借助Java提供的数据结构和算法库,可以更加高效地设计和实现操作系统中的各种数据结构和算法。 综上所述,武汉理工大学操作系统课程设计中选择使用Java作为开发语言,是出于其跨平台、多线程、异常处理和丰富的开发资源的优势。通过利用Java的特性和修炼软件工程的基本方法,可以更好地完成操作系统的设计与实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Conn_w

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

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

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

打赏作者

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

抵扣说明:

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

余额充值