【操作系统核心编程】大四的编程作业留底
邹老师布置了五个Task,不过自己时间不够,尽量做吧。感觉着实很有用,所以打算先记录下来。
1. 进程打开进程
2. 多线程
3. 线程互斥
4. 多线程操作数组
5. 多线程模型
笔者按:
使用windows对象解决临界区问题:方式有:windows执行体对象:
- 互斥对象:mutex 实现一个资源同一时刻只能被一个线程使用
- 事件对象:event 限制并发访问的线程数
- 信号量对象:semaphore
windows子系统对象:
- 临界区 critical section,同一进程内对于临界区的访问是互斥的
『临界区windows子系统对象,不是内核对象,只能用于同步单个进程中的线程,要注意跟信号量相区别。』
/*
task 2
应用Peterson算法解决临界区问题 协作线程——兄弟问题
利用Peterson算法,实现线程间的互斥。
boolean flag[2];//初值false
int turn;
do{
flag[i]:=true;
turn=j;
while(flag[j] and turn=j);
临界区;
flag[i]=false;
剩余区;
}while(1);
*/
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream> //for Dev C++ VC use #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;
volatile bool flag[2] = {0,0};
volatile int turn;
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( (char*)"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];
std::ifstream inFile; //for Dev C++ VC use ifstream inFile;
inFile.open(file,std::ifstream::in); //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);
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);
int i=m_serial;
flag[i-1] = true;
int j = (m_serial==2?1:2);
turn = j;
while(flag[m_serial-1] and turn==j)
j=j;
//begin critical_section
accnt1 = accnt1 - rand_num;
Sleep(m_delay);
accnt2 = accnt2 + rand_num;
accnt = accnt1 + accnt2;
//critical_section end
flag[i] = false;
counter++;
} while ( (accnt == 0) && (counter<10));
printf("Now accnt1+accnt2 = %05d\n",accnt);
} //end acc
/*
task 3
*/
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream> //for Dev C++ VC use #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;
CRITICAL_SECTION BRO_Add;
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( (char*)"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];
std::ifstream inFile; //for Dev C++ VC use ifstream inFile;
inFile.open(file,std::ifstream::in); //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
InitializeCriticalSection(&BRO_Add);
// 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);
srand( (unsigned)((ThreadInfo*)(p)) -> delay );
do {
printf("I am thread %d , I am doing %05dth step\n",m_serial,counter);
rand_num = rand();
EnterCriticalSection(&BRO_Add);
//begin critical_section
accnt1 = accnt1 - rand_num;
Sleep(m_delay);
accnt2 = accnt2 + rand_num;
accnt = accnt1 + accnt2;
//critical_section end
LeaveCriticalSection( &BRO_Add );
counter++;
} while ( (accnt == 0) && (counter<10));
printf("Now accnt1+accnt2 = %05d\n",accnt);
}
/*
task 4
windows 核心编程:有限缓冲区问题
测试数据:4.dat
生产者消费者算法:
生产者:计算一定范围内素数并将其放入 prime 队列(数组实现的)
消费者:将素数取出并打印出来。
临界区和事件对象解决线程独占资源问题。
Reference:
CreateEvent function: https://msdn.microsoft.com/en-us/library/ms682396(VS.85).aspx
WaitForSingleObject function: https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
*/
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream>
#include <stdio.h>
#define MAX_THREAD_NUM 64
using namespace std;
struct ThreadInfo
{
int serial;
char entity;
int from;
int to;
};
int prime[9];
int count = 0;
volatile int putArea=0;
HANDLE h_full;
HANDLE h_empty;
CRITICAL_SECTION criticalSection;
void control( char* file);
void consumerThread(void* p);
void producerThread(void* p);
////////////////////////////////////////////////////////
// main fuction
////////////////////////////////////////////////////////
int main( int agrc, char* argv[] )
{
char ch;
for(int i = 0;i < 9; i++)
{
prime[i] = 0;
}
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("4.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 control( char* file)
{
DWORD n_thread = 0;
DWORD thread_ID;
DWORD wait_for_all;
InitializeCriticalSection(&criticalSection);
// Tread Object Array
HANDLE h_Thread[MAX_THREAD_NUM];
ThreadInfo thread_info[MAX_THREAD_NUM];
h_full = CreateEvent(NULL,TRUE,TRUE,"full_event");
h_empty = CreateEvent(NULL,TRUE,TRUE,"empty_event");
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].entity;
inFile>>thread_info[n_thread].from;
inFile>>thread_info[n_thread++].to;
inFile.get();
} //end while
// Create all thread
for( int i = 0; i < (int)(n_thread); i++)
{
if(thread_info[i].entity == 'D')// Create a reader thread
{
h_Thread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(consumerThread), &thread_info[i], 0, &thread_ID);
}
else
{
h_Thread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(producerThread), &thread_info[i], 0, &thread_ID);
}
} //end for
// 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 consumerThread(void* p)
{
int m_count;
int m_serial;
int i = 0;
int readcount=0;
m_serial = ((ThreadInfo*) (p)) -> serial;
m_count = ((ThreadInfo*)(p)) -> from;
do {
WaitForSingleObject(h_full,-1);
EnterCriticalSection(&criticalSection);
while(!prime[i])
{
i=(i+1)%9;
}
printf("Consumer thread %d reads %d from postion %d.\n",m_serial,prime[i],i);
prime[i] = 0;
count--;
readcount++;
LeaveCriticalSection(&criticalSection);
SetEvent(h_empty);
Sleep(1000);
} while ( readcount<(int)m_count);
return;
}
void producerThread(void* p)
{
int m_from;
int m_to;
int m_serial;
m_serial = ((ThreadInfo*) (p)) -> serial;
m_from = ((ThreadInfo*)(p)) -> from;
m_to = ((ThreadInfo*)(p)) -> to;
int i = 0;
for(int j = (int)m_from;j < (int)m_to;j++)
{
if(j==1) continue;
int k;
for(k = 2;k <= j/2;k++)
{
if(j % k == 0) break;
}
if(k < j/2 +1) continue;
if(count == 9) break;
WaitForSingleObject(h_empty,-1);
EnterCriticalSection(&criticalSection);;
prime[putArea%9] = j;
printf("Producer thread %d writes %d to the %d postion.\n",m_serial,j,putArea%9);
putArea++;
count++;
LeaveCriticalSection(&criticalSection);
SetEvent(h_full);
Sleep(1000);
}
return;
}
原文链接:http://www.cnblogs.com/learn-to-rock/p/5894682.html

浙公网安备 33010602011771号