zoukankan      html  css  js  c++  java
  • 【操作系统核心编程】大四的编程作业留底

     邹老师布置了五个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("*********************************************
    ");
    		printf("       1.Start test
    ");
    		printf("       2.Exit to Windows
    ");
    		printf("*********************************************
    ");
    		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("
    Press any key to finish this Program. 
    Thank you test this Proggram!
    ");
    		_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 
    
    " );
    
    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.
    ");
    }// 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
    ",m_serial,counter);
    		rand_num = rand();
    		/* printf("rand_num =  %05d 
    ",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
    ",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("*********************************************
    ");
    		printf("       1.Start test
    ");
    		printf("       2.Exit to Windows
    ");
    		printf("*********************************************
    ");
    		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("
    Press any key to finish this Program. 
    Thank you test this Proggram!
    ");
    		_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 
    
    " );
    
    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.
    ");
    }// 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
    ",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
    ",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("*********************************************
    ");
    		printf("       1.Start test
    ");
    		printf("       2.Exit to Windows
    ");
    		printf("*********************************************
    ");
    		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("
    Press any key to finish this Program. 
    Thank you test this Proggram!
    ");
    		_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 
    
    " );
    
    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.
    ");
    }// 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.
    ",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.
    ",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

  • 相关阅读:
    Leetcode 238. Product of Array Except Self
    Leetcode 103. Binary Tree Zigzag Level Order Traversal
    Leetcode 290. Word Pattern
    Leetcode 205. Isomorphic Strings
    Leetcode 107. Binary Tree Level Order Traversal II
    Leetcode 102. Binary Tree Level Order Traversal
    三目运算符
    简单判断案例— 分支结构的应用
    用switch判断月份的练习
    java基本打印练习《我行我素购物系统》
  • 原文地址:https://www.cnblogs.com/learn-to-rock/p/5894682.html
Copyright © 2011-2022 走看看