【操作系统核心编程】大四的编程作业留底
邹老师布置了五个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