操作系统的有限缓冲区问题

来源:互联网 发布:thinkpad 知乎 编辑:程序博客网 时间:2024/04/27 20:25
 

/* 有限缓冲区问题 */

#include <windows.h>
#include <conio.h>
#include <fstream.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <iostream.h>
#define INTE_PER_SEC  1000
#define MAX_THREAD_NUM  64
#define MAX_FILE_NUM  32
#define MAX_STR_LEN  32

#define MAX_PRIME_NUM 9

//the struct of threadinfo
struct ThreadInfo
{
 int serial;
 char entity;
 int start;
 int end;
};

//the struct of queue
typedef struct
{
 int *base;
 int front;
 int rear;
}PrimeQueue;


//define some global variables
HANDLE h_Thread[MAX_THREAD_NUM];
ThreadInfo  thread_info[MAX_THREAD_NUM];
CRITICAL_SECTION  critical[2];
HANDLE h_Mutex1;
HANDLE h_Mutex2;
HANDLE empty_semaphore;
HANDLE full_semaphore;
PrimeQueue prime_Q;
int prime[MAX_PRIME_NUM];//store primes
volatile int w_count = 0;
volatile int d_count = 0;

void control_thread ( char *file);
void WritePrimeThread ( void *p );
void DisPrimeThread ( void *p );
int FindPrime ( int start, int end );


void InitQueue( PrimeQueue &Q,int p[])
{
 Q.base = p;
 Q.front = Q.rear = 0;
}

void EnQueue( PrimeQueue &Q,int e)
{
 Q.base[Q.rear] = e;
 Q.rear = (Q.rear + 1) % MAX_PRIME_NUM;
}

void DeQueue( PrimeQueue &Q, int &e)
{
 e = Q.base[Q.front];
 Q.front = (Q.front + 1) % MAX_PRIME_NUM;
}

 

////////////////////////////////////////////////////////
// main fuction
////////////////////////////////////////////////////////

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

 while ( TRUE )
 {
  // Cleare screen
  system( "cls" );
  // display prompt info
  printf("*********************************************\n");
  printf("       1.Start test\n");
  printf("       2.Exit to Windows\n");
  printf("*********************************************\n");
  printf("Input your choice(1or2): ");
  // if the number inputed is error, retry!
  do{
   ch = (char)_getch();
  }while( ch != '1' && ch != '2');

  system ( "cls" );
  if ( ch == '1')
   control_thread ("ex4.dat");
  else if ( ch == '2')
   return 0;
  printf("\nPress any key to finish this Program. \nThank you test this Program!\n");
  _getch();
 } //end while
} //end main


///////////////////////////////////////////////////////////////
//control_thread
//////////////////////////////////////////////////////////////

void control_thread( char* file )
{
 DWORD n_thread = 0;
 DWORD thread_ID;
 DWORD wait_for_all;
 DWORD dwMilliseconds=5000;

 /*initialize prime array*/
 for (int i=0; i< MAX_PRIME_NUM; i++)
  prime[i]=-1;

 /*initialize queue*/
 InitQueue(prime_Q,prime);

 ifstream  inFile;
 inFile.open( file );  //open file

 while ( inFile )
 {
  inFile>>thread_info[n_thread].serial;
  inFile>>thread_info[n_thread].entity;
  inFile>>thread_info[n_thread].start;
  inFile>>thread_info[n_thread++].end;
  inFile.get();
 } //end while
 for(i =0; i < 2;i++)
 {
  InitializeCriticalSection (&critical[i]);
 }
 empty_semaphore = CreateSemaphore(NULL,MAX_PRIME_NUM,MAX_PRIME_NUM,"semaphore_for_empty");
 full_semaphore = CreateSemaphore(NULL,0,MAX_PRIME_NUM,"semaphore_for_full");

 h_Mutex1 = CreateMutex(NULL,FALSE,"mutex_for_rear");
 h_Mutex2 = CreateMutex(NULL,FALSE,"mutex_for_front");

 for( i = 0; i < (int)(n_thread); i++)
 {
  if(thread_info[i].entity == 'W' || thread_info[i].entity == 'w')
  {
   // Create WritePrime Thread
      h_Thread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(WritePrimeThread), &thread_info[i], 0, &thread_ID);
   w_count++;
  } 
  else
  {
   // Create DisPrime Thread
      h_Thread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(DisPrimeThread), &thread_info[i], 0, &thread_ID);
   d_count++;
  }
 } //end for

 // waiting all thread will been finished
 //wait_for_all = WaitForMultipleObjects(n_thread,h_Thread,TRUE, dwMilliseconds);
 wait_for_all = WaitForMultipleObjects(n_thread,h_Thread,TRUE, -1);
 //if(wait_for_all == WAIT_TIMEOUT)
  //printf("all the WritePrimeThreads have finished,but left a DisPrimeThread\n");
 //else
 printf("All writer and displayer thread have finished Operating.\n");
}// end control_thread


int FindPrime(int start,int end)
{
 int k;
 int pos=start;
 if(pos == 1)pos++;
 while(pos<=end)
 {
  k=(int)sqrt(pos);
  for(int i=2;i <=k;i++)
   if(pos%i==0)break;
  if(i>k)return pos;
  pos++;
 }
 return 0;
}

////////////////////////////////////
// WritePrime Thread
///////////////////////////////////

void WritePrimeThread(void* p)
{
 DWORD wait_for_mutex1;
 DWORD wait_for_semaphore;
 int m_serial;
 int m_start;
 int m_end;
 int rand_num;

 //get info from para
 m_serial = ((ThreadInfo*) (p)) -> serial;
 m_start  = int (((ThreadInfo*)(p)) -> start);
 m_end  = int (((ThreadInfo*)(p)) -> end);

 
 srand( (unsigned)m_start );
 rand_num = rand();

 while(m_start<=m_end  )
 {
  Sleep(rand_num);
  
  //get a prime
  int get_prime = FindPrime(m_start,m_end);
  if( get_prime )
  { 
   m_start=get_prime+1;
  }
  else
  {
   m_start=m_end+1;
   continue;
  }
  if(d_count == 0)return;

  //try to entry the CriticalSection
  wait_for_semaphore = WaitForSingleObject(empty_semaphore,INFINITE);
  wait_for_mutex1 = WaitForSingleObject( h_Mutex1,INFINITE);

  EnQueue(prime_Q,get_prime);
  printf("Prime_Find thread %d have found a prime %2d\n",m_serial,get_prime);
  
  //now to LeaveCriticalSection
  ReleaseMutex( h_Mutex1 );
  ReleaseSemaphore(full_semaphore,1,NULL);
  
 }//end while
 
 EnterCriticalSection(&critical[0]);
 w_count--;
 LeaveCriticalSection(&critical[0]);
 printf("Prime_Find thread %d finished Prime Find\n",m_serial);
}//end writeprime thread

 

////////////////////////////////////
//DisPrimeThread
///////////////////////////////////

void DisPrimeThread(void* p)
{
 int m_serial;
 int m_start;
 DWORD wait_for_mutex2;
 DWORD wait_for_semaphore;
 int rand_num;

 //get info from para
 m_serial = ((ThreadInfo*) (p)) -> serial;
 m_start = int (((ThreadInfo*)(p)) -> start);

 srand( (unsigned)m_start );
 rand_num = rand();
 while( m_start )
 {
  Sleep(rand_num);
  
  if(w_count == 0)return;

  //try to entry the CriticalSection
  wait_for_semaphore = WaitForSingleObject(full_semaphore,INFINITE);
  wait_for_mutex2 = WaitForSingleObject( h_Mutex2,INFINITE);
  
  int dis;
  DeQueue(prime_Q, dis);
  printf("Prime_Display thread %d  displays  %d\n",m_serial,dis);

  //now to LeaveCriticalSection
  ReleaseMutex( h_Mutex2 );
  ReleaseSemaphore(empty_semaphore,1,NULL);

  m_start--;
 }//end while
 
 EnterCriticalSection(&critical[1]);
 d_count--;
 LeaveCriticalSection(&critical[1]);

 printf("Prime_Display thread %d finished Prime Display \n",m_serial);
}//end DisPrimeThread

原创粉丝点击