首页 范文大全 古典文学 职场知识 中国文学 公文书信 外国名著 寓言童话 百家讲坛 散文/诗歌 美文欣赏 礼仪知识 民俗风情
  • 工作总结
  • 工作计划
  • 心得体会
  • 竞聘演讲
  • 会议发言
  • 爱国演讲
  • 就职演说
  • 开业开幕
  • 思想学习
  • 征文演讲
  • 经验材料
  • 述职报告
  • 调研报告
  • 工作汇报
  • 年终总结
  • 申报材料
  • 学习体会
  • 企划方案
  • 活动方案
  • 技巧经验
  • 模板范例
  • 思想宣传
  • 经济工作
  • 工作报告
  • 组织人事
  • 反腐倡廉
  • 慰问贺电
  • 先进事迹
  • 思想汇报
  • 入党申请书
  • 党会发言
  • 先进性教育
  • 入团申请书
  • 个人简历
  • 演讲稿
  • 调查报告
  • 实习报告
  • 和谐社会
  • 观后感
  • 读后感
  • 作文范文
  • 自我鉴定
  • 讲话稿
  • 自查报告
  • 进程(线程)同步和互斥实验报告

    时间:2020-11-15 12:34:44 来源:蒲公英阅读网 本文已影响 蒲公英阅读网手机站

    相关热词搜索:线程 进程 同步

      操 作 系 统 实 验 报 告 课程名称

     操作系统

     实验名称

     进程(线程)的同步与互斥

     成绩

      学生姓名

      作业君

      专业

      软件工程

      班级、学号

      同组者姓名

      无

      实验日期

     2020

      一、实验题目: : 进程(线程)的同步与互斥 二、实验目的 :

     自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的 PCB 内容 、组织的变化,理解进程与其 PCB 间的一一对应关系。

     1.掌握基本的同步与互斥算法,理解生产者消费者模型。

     2.学习使用 Windows 中基本的同步对象,掌握相关 API 的使用方法。

     3.了解 Windows 中多线程的并发执行机制,实现进程的同步与互斥 三、实验内容与要求 :

     1.实验内容 以生产者/消费者模型为依据,在 Windows 环境下创建一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。

     2.实验要求 学习并理解生产者/消费者模型及其同步/互斥规则; 学习了解 Windows 同步对象及其特性; 熟悉实验环境,掌握相关 API 的使用方法; 设计程序,实现生产者/消费者进程(线程)的同步与互斥;

     四、算法描述(含数据结构定义)或流程图

     #include <Windows.h> #include <iostream> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std;

      #define MAX_THREAD_NUM 64

      //最大线程数 #define INTE_PER_SEC 1000

      //延迟时间的毫秒值 const int SIZE_OF_BUFFER = 10;

     //缓冲区长度 int ProductID = 0;

      //产品号 int ConsumeID = 0;

     //将被消耗的产品号 int in = 0;

     //产品进缓冲区时的缓冲区下标 int out = 0;

      //产品出缓冲区时的缓冲区下标 bool running = true;

     //判断程序能否继续执行的逻辑值 int g_buffer[SIZE_OF_BUFFER];

      //缓冲区是个循环队列 HANDLE g_hMutex;

     //公有信号量,用于线程间的互斥 HANDLE g_hFullSemaphore;

      //生产者的私有信号量,当缓冲区满时迫使生产者等待 HANDLE g_hEmptySemaphore;

      //消费者的私有信号量,当缓冲区空时迫使消费者等待

     //定义一个结构体用于存储线程的信息 struct ThreadInfo {

     int serial;

      //线程号

     char entity;

     //线程类别(生产者或消费者)

     double delay;

      //等待时间

     double persist; //操作时间 };

     //生产者 void Producer(void* p) {

     //定义变量用于存储当前线程的信息

     DWORD m_delay;

     DWORD m_persist;

     int m_serial;

      //从参数中获得信息

     m_serial = ((ThreadInfo*)(p))->serial;

     m_delay = (DWORD)(((ThreadInfo*)(p))->delay * INTE_PER_SEC);

     m_persist = (DWORD)(((ThreadInfo*)(p))->persist * INTE_PER_SEC);

      while (running)

     {

      //P 操作

      cout << "生产者线程 " << m_serial << " 请求生产." << endl;

      WaitForSingleObject(g_hEmptySemaphore, INFINITE);

      cout << "生产者线程 " << m_serial << " 请求独占缓冲区." << endl;

      WaitForSingleObject(g_hMutex, INFINITE);

     Sleep(m_delay);

     //延迟等待

      //生产一个产品

      cout << "生产者线程 " << m_serial << " 生产 " << ++ProductID << " 号产品成功." << endl;

      cout << "生产者线程 " << m_serial << " 请求将产品 " << ProductID << " 投入缓冲区." << endl;

      //把新生产的产品放入缓冲区

      g_buffer[in] = ProductID;

      in = (in +1)%SIZE_OF_BUFFER;

      Sleep(m_persist);

      //操作等待

      cout << "生产者线程 " << m_serial << " 将产品 " << ProductID << " 投入缓冲区中成功." << endl;

     //输出缓冲区当前的状态

      cout << "****************************" << endl

     << "\n 当前缓冲区情况如图(■代表已有产品,□代表没有产品):

      " << endl;

      for (int i = 0;i < SIZE_OF_BUFFER;++i)

      {

     if (g_buffer[i] != 0)

      cout << "■";

     else

     cout << "□";

      }

      cout << "\n\n****************************\n" << endl;

     //V 操作

      ReleaseMutex(g_hMutex);

      ReleaseSemaphore(g_hFullSemaphore, 1, NULL);

     } }

     //消费者 void Consumer(void* p) {

     DWORD m_delay;

     DWORD m_persist;

     int m_serial;

     //从参数中获得信息

     m_serial = ((ThreadInfo*)(p))->serial;

     m_delay = (DWORD)(((ThreadInfo*)(p))->delay * INTE_PER_SEC);

     m_persist = (DWORD)(((ThreadInfo*)(p))->persist * INTE_PER_SEC);

     while (running)

     {

      //P 操作

      cout << "消费者线程 " << m_serial << " 请求消费." << endl;

      WaitForSingleObject(g_hFullSemaphore, INFINITE);

      cout << "消费者线程 " << m_serial << " 请求独占缓冲区." << endl;

      WaitForSingleObject(g_hMutex,INFINITE);

     Sleep(m_delay); //延迟等待

      //从缓冲区中取出一个产品

      cout << "消费者线程 " << m_serial << " 请求取出一个产品." << endl;

      ConsumeID = g_buffer[out];

      g_buffer[out] = 0;

      out = (out + 1) % SIZE_OF_BUFFER;

      cout << "消费者线程 " << m_serial << " 取出产品 " << ConsumeID << " 成功." << endl;

     //消耗一个产品

      cout << "消费者线程 " << m_serial << " 开始消费消费产品 " << ConsumeID << "." << endl;

      Sleep(m_persist);

      cout << "消费者线程 " << m_serial << " 消费产品 " << ConsumeID << " 成功." << endl;

     //输出缓冲区当前的状态

      cout << "****************************" << endl

     << "\n 当前缓冲区情况如图:

      " << endl;

      for (int i = 0;i < SIZE_OF_BUFFER;++i)

      {

     if (g_buffer[i] != 0)

      cout << "■";

     else

     cout << "□";

      }

      cout << "\n\n****************************\n" << endl;

     //V 操作

      ReleaseMutex(g_hMutex);

      ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);

     } }

     void prod_cons() {

     //创建互斥信号量

     g_hMutex = CreateMutex(NULL, FALSE, NULL);

     //创建同步信号量

     g_hEmptySemaphore = CreateSemaphore(NULL, SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);

     g_hFullSemaphore = CreateSemaphore(NULL, 0, SIZE_OF_BUFFER, NULL);

     srand((unsigned)time(NULL));

     //以时间函数为种子

     const unsigned short THREADS_COUNT = rand() % 5 + 5; //总的线程数(随机生成)

      //线程对象的数组

     HANDLE hThreads[MAX_THREAD_NUM];

     ThreadInfo thread_info[MAX_THREAD_NUM];

      DWORD thread_ID; //线程 ID

     int num = 0;

      //临时变量,用于循环语句

     cout << "系统开始模拟,并自动生成模拟数据..." << endl;

     system("pause"); //暂停确认开始执行

     cout << "线程总数:" << THREADS_COUNT << endl;

      //循环随机生成各个线程的信息

     while (num != THREADS_COUNT)

     {

      thread_info[num].serial = num + 1;

      if (rand() % 2 == 1)

     thread_info[num].entity = "P";

      else

     thread_info[num].entity = "C";

      thread_info[num].delay = rand() % 5 + 1;

      thread_info[num].persist = rand() % 6 + 2;

      num++;

     }

      cout << "\n 系统生成数据结束,模拟数据如下:" << endl

      << "线程号

     线程类别

     延迟时间

     操作时间" << endl;

     for (int x = 0;x < THREADS_COUNT;x++)

      cout << "

     " << thread_info[x].serial << "\t"

      << "

      " << thread_info[x].entity << "\t"

      << "

     " << thread_info[x].delay << "\t\t"

      << "

      " << thread_info[x].persist << endl;

     cout << "\n\n==================生产者-消费者 开始==================\n" << endl;

      //创建线程

     for (int i = 0;i < THREADS_COUNT;i++)

     {

      //创建生产者线程

      if (thread_info[i].entity == "P")

     hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), &thread_info[i], 0, &thread_ID);

      //创建消费者线程

      else

     hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), &thread_info[i], 0, &thread_ID);

     }

      while (running)

     {

      if (getchar())

      {

     //按回车后终止程序运行

     running = false;

      }

     }

     cout << "系统模拟结束..." << endl; } int main() {

     cout << "\n==================生产者-消费者 模拟==================\n" << endl;

     prod_cons(); }

     五、实验过程

     1、记录生产者和消费者的同步执行过程。

      2、分析 Producer 函数和 Consumer 函数的功能,并画出对应的程序流程图。

      Producer 函数:调用函数,获取资源情况,然后判断条件是否满足,判断是否执行,接着发出生产请求,请求通过后独占缓冲区资源,接着生产-一个产品投入缓冲区,成功后释放所占缓冲区资源,到此此函数执行完成。

     consumer 函数:

     通过用变量提取保存提取当前资源信息, 然后判断是否执行, 接着发出消费请求, 请求通过后独占缓冲区资源, 接着消费一个产品取出缓冲区, 成功后释放所占缓冲区资源, 到此此函数执行完成。

     3、试将同步和互斥的 P 操作颠倒次序执行,观察并分析程序的运行情况。

     答:

     如将同步和互斥的 P 操作颠倒次序执行,程序会产生死锁。因为这个操作会先独占缓冲区的资源,然后才发送请求。如果生产或者消费请求无法通过而一直等待下去的话,则无法释放资源,进而产生程序的死锁,使得程序无法运行!

     六、实验总结

     通过本次实验,让我对线程的同步与互斥技术有了比较深刻的了解,生产者消费者问题是研究多线线程程序绕不开的问题,它的描述是有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无休止的进行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。

    • 范文大全
    • 职场知识
    • 精美散文
    • 名著
    • 讲坛
    • 诗歌
    • 礼仪知识