⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 设计报告.txt

📁 主要功能: 1、 包括顾客信息、货品信息、定单信息的管理。 2、 按月统计销售业绩。 3、 报表设计。 4、 系统维护。
💻 TXT
📖 第 1 页 / 共 4 页
字号:
void acc_right(void* p)
{
 DWORD m_delay;
 int m_serial;
 int tmp1 , tmp2, rand_num;
 int counter = 0;

//get info from para

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

 do
 {

  flag[m_serial]=true;
  turn=1-m_serial;
  while (flag[1-m_serial] && turn==1-m_serial);

//begin critical_section

  printf("I am thread  %d , I am doing  %05dth step\n",m_serial,counter);
  tmp1 = accnt1;
  tmp2 = accnt2;
  rand_num = rand();

  accnt1 = tmp1 - rand_num;
  Sleep(m_delay);
  accnt2 = tmp2 + rand_num;
  accnt = accnt1 + accnt2;
//critical_section  end

  flag[m_serial]=false;

  counter++;
  printf("Now the random number is %d ; and accnt1+accnt2 =  %05d\n\n",rand_num,accnt);
 } while (counter<10); 
 printf("At last of thread %d accnt1+accnt2 =  %05d\n",m_serial,accnt);
} //end acc_right

void acc_wrong(void* p)
{
 DWORD m_delay;
 int m_serial;
 int tmp1 , tmp2, rand_num;
 int counter = 0;

//get info from para

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

 do
 {

//begin critical_section

  printf("I am thread  %d , I am doing  %05dth step\n",m_serial,counter);
  tmp1 = accnt1;
  tmp2 = accnt2;
  rand_num = rand();

  accnt1 = tmp1 - rand_num;
  Sleep(m_delay);
  accnt2 = tmp2 + rand_num;
  accnt = accnt1 + accnt2;
//critical_section  end

  counter++;
  printf("Now the random number is %d ; and accnt1+accnt2 =  %05d\n\n",rand_num,accnt);
 } while (counter<10); 
 printf("At last of thread %d accnt1+accnt2 =  %05d\n",m_serial,accnt);
} //end acc_wrong

任务三  同步对象解决临界区问题
一、基本信息
实践题目:同步对象解决临界区问题-兄弟问题
二、实践内容简要描述
实践目标:
学会使用Win32同步对象(临界区内核对象、信号量内核对象等);
用同步对象解决临界区问题-兄弟问题。
实践内容:
设置竞争条件:
定义两个全局变量:accnt1和accnt2,初值都为零;
创建两个线程acc1和acc2;
(1)获得一个随机数
(2)从accnt1减去这个随机数;
(3)将这个随机数加到accnt2中;
(4)正确的话,accnt1+accnt2=0。
设置条件使其不正确。
用Win32提供的同步对象实现两个线程的协作,以解决以上临界区问题,即兄弟问题。
三、实践报告主要内容
设计思路:
用一个临界区变量可以实现两个线程对临界区的访问,在每个线程进入临界区前调用EnterCriticalSection函数申请权限,离开临界区后调用LeaveCriticalSection函数释放资源从而让其他线程可以访问,这样可以阻止两个线程同时处于临界区。
主要数据结构:
struct ThreadInfo
{
 int serial;
 double delay;
};//存放线程的ID及其执行延时(模拟兄弟在外创业的时间)

/*volatile*/  int accnt1 = 0;  //借款帐户中金额
/*volatile*/  int accnt2 = 0;  //还款帐户中金额
/*volatile*/  int accnt;  //借款帐户与还款帐户金额总和,应保持为0
CRITICAL_SECTION g_cs; //临界区变量,用于两个线程的互斥访问
主要代码结构:
do{
entry section
critical section
exit section
remainder section
}while(1);
主要代码分析:
1.entry section用于在进入临界区时的等待
EnterCriticalSection(&my_section); 
2.exit section用于离开临界区后的发送信号的工作,通知另外的线程可以进入临界区
 LeaveCriticalSection(&my_section);
四、实践结果
基本数据:
 
源程序代码行数 完成实践投入的总时间 资料查阅时间 编程调试时间 源程序文件    
193 0.2小时 0.1小时 0.1小时 ex3.cpp  
测试数据设计:
“ex3.dat”文件内容如下:
 0  1
1  1
2  1
3  1
4  1
测试结果分析:
运行结果图如下所示:
Now, We begin to read thread Information to thread_info array
I am thread  0 , I am doing  00000th step
I am thread  1 , I am doing  00000th step
Now the random number is 22413 ; and accnt1+accnt2 =  00000
I am thread  2 , I am doing  00000th step
Now the random number is 17802 ; and accnt1+accnt2 =  00000
I am thread  3 , I am doing  00000th step
Now the random number is 5286 ; and accnt1+accnt2 =  00000
I am thread  4 , I am doing  00000th step
Now the random number is 23304 ; and accnt1+accnt2 =  00000
I am thread  0 , I am doing  00001th step
Now the random number is 12270 ; and accnt1+accnt2 =  00000
I am thread  1 , I am doing  00001th step
Now the random number is 12170 ; and accnt1+accnt2 =  00000
I am thread  2 , I am doing  00001th step
Now the random number is 4729 ; and accnt1+accnt2 =  00000
I am thread  3 , I am doing  00001th step
Now the random number is 28247 ; and accnt1+accnt2 =  00000
I am thread  4 , I am doing  00001th step
Now the random number is 3819 ; and accnt1+accnt2 =  00000
I am thread  0 , I am doing  00002th step
Now the random number is 2578 ; and accnt1+accnt2 =  00000
I am thread  1 , I am doing  00002th step
Now the random number is 21931 ; and accnt1+accnt2 =  00000
I am thread  2 , I am doing  00002th step
Now the random number is 170 ; and accnt1+accnt2 =  00000
I am thread  3 , I am doing  00002th step
Now the random number is 18300 ; and accnt1+accnt2 =  00000
I am thread  4 , I am doing  00002th step
Now the random number is 2054 ; and accnt1+accnt2 =  00000
I am thread  0 , I am doing  00003th step
Now the random number is 538 ; and accnt1+accnt2 =  00000
I am thread  1 , I am doing  00003th step
Now the random number is 12469 ; and accnt1+accnt2 =  00000
I am thread  2 , I am doing  00003th step
Now the random number is 7825 ; and accnt1+accnt2 =  00000
I am thread  3 , I am doing  00003th step
Now the random number is 14181 ; and accnt1+accnt2 =  00000
I am thread  4 , I am doing  00003th step
Now the random number is 5984 ; and accnt1+accnt2 =  00000
I am thread  0 , I am doing  00004th step
Now the random number is 17150 ; and accnt1+accnt2 =  00000
I am thread  1 , I am doing  00004th step
Now the random number is 15529 ; and accnt1+accnt2 =  00000
At last of thread 0 accnt1+accnt2 =  00000
I am thread  2 , I am doing  00004th step
Now the random number is 31878 ; and accnt1+accnt2 =  00000
At last of thread 1 accnt1+accnt2 =  00000
I am thread  3 , I am doing  00004th step
Now the random number is 3842 ; and accnt1+accnt2 =  00000
At last of thread 2 accnt1+accnt2 =  00000
I am thread  4 , I am doing  00004th step
Now the random number is 5953 ; and accnt1+accnt2 =  00000
At last of thread 3 accnt1+accnt2 =  00000
Now the random number is 23968 ; and accnt1+accnt2 =  00000
At last of thread 4 accnt1+accnt2 =  00000
All threads have finished Operating.
Press any key to finish this Program.
程序运行过程中,线程1或线程2向accnt1中借款,一定延时后向accnt2中还款,总额accnt均为0,程序运行结果完全正确。
五、实践体会
 使用临界区变量解决临界区问题实现起来比软件方法简单明了,并且可以应用到多进程的情况之中,通过这次实验我基本了解了临界区变量的使用方法和作用,其实,解决临界区问题的方法相当的多,从中选取一种合适的是要很多经验积累的。

六、参考文献
1、MSDN

附:源程序代码
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream.h>
#include <stdio.h>
#include <time.h>
#define INTE_PER_SEC  500
#define MAX_THREAD_NUM  64
#define RIGHT_VERSION TRUE
#define WRONG_VERSION FALSE

CRITICAL_SECTION  my_section;

struct ThreadInfo
{
 int serial;
 double  delay;
};

/*volatile*/  int accnt1 = 0; 
/*volatile*/  int accnt2 = 0;
/*volatile*/  int accnt;

void account( char* file,BOOL version);
void acc_right(void* p);
void acc_wrong(void* p);

////////////////////////////////////////////////////////
// main function
////////////////////////////////////////////////////////

int main( int agrc, char* argv[] )
{
 char ch;

 while ( TRUE )
 {
  // Clear screen
  system( "cls" );

  // display prompt info
  printf("*********************************************\n");
  printf("       1.Start the right version(with the using of CRITICAL_SECTION)\n");
  printf("       2.Start the wrong version(without any algorithm of synchronization)\n");
  printf("       3.Exit to Windows\n");
  printf("*********************************************\n");
  printf("Input your choice(1 、2 or 3): ");

  // if the number inputed is error, retry!
  do
  {
   ch = (char)_getch(); 
  }while ( ch != '1' && ch != '2'&& ch != '3');

  system ( "cls" );
  if ( ch == '1')
   account("ex3.dat",RIGHT_VERSION);
  else if (ch =='2')
   account("ex3.dat",WRONG_VERSION);
  else if ( ch == '3')
   return 0;
  printf("\nPress any key to finish this Program. \n");
  _getch();
 } //end while
} //end main

void account( char* file,BOOL version)
{
 DWORD n_thread = 0;
 DWORD thread_ID;
 DWORD wait_for_all;
// Tread Object Array

 HANDLE h_Thread[MAX_THREAD_NUM];
 ThreadInfo  thread_info[MAX_THREAD_NUM];

 ifstream  inFile;
 inFile.open(file);  //open file
 printf( "Now, We begin to read thread Information to thread_info array \n\n" );

 while ( inFile )
 {
  // read every thread info
  inFile>>thread_info[n_thread].serial;
  inFile>>thread_info[n_thread++].delay;
  inFile.get();
 } //end while

// initialize the data
 srand((unsigned)time(NULL));
 accnt1=0;
 accnt2=0;
// Create all thread
 if (version==RIGHT_VERSION)
 {
  InitializeCriticalSection(&my_section);  //init critical section
  for ( int i = 0; i < (int)(n_thread); i++)
  {
   // Create a thread
   h_Thread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(acc_right), &thread_info[i], 0, &thread_ID);
  } //end for
 } else
 {
  for ( int i = 0; i < (int)(n_thread); i++)
  {
   // Create a thread
   h_Thread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(acc_wrong), &thread_info[i], 0, &thread_ID);
  } //end for
 }
// Create thread
// waiting all thread will been finished
 wait_for_all = WaitForMultipleObjects(n_thread,h_Thread,TRUE, -1);
 printf("All threads have finished Operating.\n");
}// end account

void acc_right(void* p)
{
 DWORD m_delay;
 int m_serial;
 int tmp1 , tmp2, rand_num;
 int counter = 0;
//get info from para
 m_serial = ((ThreadInfo*) (p)) -> serial;
 m_delay  = (DWORD) (((ThreadInfo*)(p)) -> delay*INTE_PER_SEC);
 do
 {
  EnterCriticalSection(&my_section);
//begin critical_section
  printf("I am thread  %d , I am doing  %05dth step\n",m_serial,counter);
  tmp1 = accnt1;
  tmp2 = accnt2;
  rand_num = rand();
  accnt1 = tmp1 - rand_num;
  Sleep(m_delay);
  accnt2 = tmp2 + rand_num;
  accnt = accnt1 + accnt2;
//critical_section  end
  LeaveCriticalSection(&my_section);
  counter++;
  printf("Now the random number is %d ; and accnt1+accnt2 =  %05d\n\n",rand_num,accnt);
 } while (counter<5); 
 printf("At last of thread %d accnt1+accnt2 =  %05d\n",m_serial,accnt);
} //end acc_right

void acc_wrong(void* p)
{
 DWORD m_delay;
 int m_serial;
 int tmp1 , tmp2, rand_num;
 int counter = 0;
//get info from para
 m_serial = ((ThreadInfo*) (p)) -> serial;
 m_delay  = (DWORD) (((ThreadInfo*)(p)) -> delay*INTE_PER_SEC);
 do
 {
//begin critical_section
  printf("I am thread  %d , I am doing  %05dth step\n",m_serial,counter);
  tmp1 = accnt1;
  tmp2 = accnt2;
  rand_num = rand();
  accnt1 = tmp1 - rand_num;
  Sleep(m_delay);
  accnt2 = tmp2 + rand_num;
  accnt = accnt1 + accnt2;
//critical_section  end
  counter++;
  printf("Now the random number is %d ; and accnt1+accnt2 =  %05d\n\n",rand_num,accnt);
 } while (counter<5); 
 printf("At last of thread %d accnt1+accnt2 =  %05d\n",m_serial,accnt);
} //end acc_wrong

任务四  同步对象解决有限缓冲区问题
一、基本信息
实践题目:同步对象解决有限缓冲区问题
二、实践内容简要描述

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -