您的位置:首页 > 其它

用Peterson算法实现临界区的控制

2016-02-27 11:08 323 查看
定义两个全局变量初始值为0,用两个线程分别完成加1减1操作,然后相加两全局变量,结果为0则正确

 设计思路  

利用Peterson算法,实现线程间的互斥。 

boolean flag[2];//初值false int turn;  do{ 

   flag[i]:=true;    turn=j; 

   while(flag[j] and turn=j);        

临界区;   

 flag[i]=false;        

剩余区;   

}while(1); 

i为线程自身的序号减去1,j为2减去该线程的序号。 

当某一进程试图访问临界区时,若另一进程已在访问临界区,则该线程通过循环等待直至另一线程退出临界区方可执行。

#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream.h>
#include <stdio.h>

#define INTE_PER_SEC  1000
#define MAX_THREAD_NUM  64

struct ThreadInfo
{
int	serial;
double	delay;
};

volatile  int accnt1 = 0; /*  in the memory */
volatile  int accnt2 = 0;

void account( char* file);
void acc(void* p);

////////////////////////////////////////////////////////
// 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')
account("sm6.dat");
else if ( ch == '2')
return 0;
printf("\nPress any key to finish this Program. \nThank you test this Proggram!\n");
_getch();
} //end while
} //end main

void account( char* file)
{
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

// Create all thread
for( int i = 0; i < (int)(n_thread); i++)
{
// Create a thread
h_Thread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(acc), &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(void* p)
{
DWORD m_delay;
int m_serial;

int rand_num, accnt,counter = 0;;

//get info froam para

m_serial = ((ThreadInfo*) (p)) -> serial;
m_delay  = (DWORD) (((ThreadInfo*)(p)) -> delay*INTE_PER_SEC);
boolean flag[2];
flag[0]=flag[1]=false;
int turn,a;

srand( (unsigned)((ThreadInfo*)(p)) -> delay );

do {
printf("I am thread  %d , I am doing  %05dth step\n",m_serial,counter);
rand_num = rand();
printf("rand_num =  %05d \n",rand_num);
//Sleep(m_delay);

//begin critical_section

flag[m_serial-1]=true;
a=2-m_serial;

turn=a;

while(flag[a]&&turn==a);

accnt1 = accnt1 - rand_num;
//Sleep(m_delay);
accnt2 = accnt2 + rand_num;
accnt = accnt1 + accnt2;
/*critical section*/ ;

flag[m_serial-1]=false;
printf("Now accnt1+accnt2 =  %05d\n",accnt);
Sleep(10*m_serial+700);  //wait a moment

//critical_section  end

counter++;
} while ( (accnt == 0) && (counter<10));
printf("Now accnt1+accnt2 =  %05d\n",accnt);
} //end acc
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: