zoukankan      html  css  js  c++  java
  • 操作系统实验 windows编程多线程 生产者消费者问题 画圆画方(内置bug版)

    实验3:随便写的

     1 #include <windows.h>  
     2 #include <string>  
     3 #include <stdio.h>
     4 #pragma warning(disable:4996)  
     5 
     6 CRITICAL_SECTION cs;
     7 
     8 int cnt;
     9 
    10 DWORD WINAPI Thread( LPVOID lpParam ) 
    11 {
    12     int n = (int)lpParam;
    13 
    14     if ( n == 1 )
    15         for ( int i = 1; i <= 1000; i++ )
    16         {
    17             EnterCriticalSection(&cs);
    18             printf( "第%d个线程输出%d
    ", n, i );
    19             LeaveCriticalSection(&cs);
    20             Sleep(500);
    21         }
    22     if ( n == 2 )
    23         for ( int i = 1000; i >= 1; i-- )
    24         {
    25             EnterCriticalSection(&cs);
    26             printf( "第%d个线程输出%d
    ", n, i );
    27             LeaveCriticalSection(&cs);
    28             Sleep(500);
    29         }
    30 
    31     return 0;
    32 }
    33 
    34 int main()  
    35 {  
    36     cnt = 0;
    37 
    38     DWORD ThreadID;
    39     HANDLE hThread[2];
    40     InitializeCriticalSection(&cs);
    41     for ( int i = 0; i < 2; i++ )
    42     {
    43         hThread[i] = CreateThread( NULL, 0, Thread, (LPVOID)(i+1), 0, &ThreadID );
    44         printf( "Thread %d has been created
    ", i );
    45     }
    46     WaitForMultipleObjects( 2, hThread, TRUE, INFINITE );
    47 
    48     DeleteCriticalSection(&cs);
    49     return 0;  
    50 }
    View Code

    实验4:https://blog.csdn.net/morewindows/article/details/7577591

    修改了部分代码并添加了注释

      1 #include <stdio.h>    
      2 #include <process.h>    
      3 #include <windows.h>   
      4 
      5 const int THREADNUM = 4; 
      6 const int END_PRODUCE_NUMBER = 9;    //要生产的产品个数  
      7 const int BUFFER_SIZE = 4;          //缓冲区个数    
      8 int g_Buffer[BUFFER_SIZE];          //缓冲池    
      9 int g_i, g_j;                        //信号量与关键段    
     10 
     11 CRITICAL_SECTION g_cs;    
     12 HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull;    
     13 
     14 int data=0;  
     15 
     16 //生产者线程函数    
     17 unsigned int __stdcall ProducerThreadFun(PVOID pM)    
     18 {    
     19     while( data < END_PRODUCE_NUMBER )  
     20     {  
     21         //等待有空的缓冲区出现    
     22         WaitForSingleObject( g_hSemaphoreBufferEmpty, INFINITE );    
     23 
     24         //互斥的访问缓冲区    
     25         EnterCriticalSection(&g_cs);   
     26 
     27         //如果投放了足够多的数据,就直接离开临界区
     28         if( data == END_PRODUCE_NUMBER )  
     29         {  
     30             LeaveCriticalSection(&g_cs);  
     31             break;  
     32         }  
     33 
     34         //否则投放数据
     35         data++;  
     36         g_Buffer[g_i] = data;    
     37 
     38 
     39         printf("%d号生产者在缓冲池中第%d个缓冲区中投放数据%d
    
    ", GetCurrentThreadId(), g_i, g_Buffer[g_i]);   
     40 
     41         //循环投放数据
     42         g_i = ( g_i + 1 ) % BUFFER_SIZE; 
     43         LeaveCriticalSection(&g_cs);
     44 
     45         Sleep(50);  
     46 
     47         //将Full信号量+1,表示生产了一个数据可以取了  
     48         ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);    
     49     }  
     50      
     51     printf("生产者完成任务,线程结束运行
    
    ");    
     52     return 0;    
     53 }    
     54 
     55 //消费者线程函数    
     56 unsigned int __stdcall ConsumerThreadFun(PVOID pM)    
     57 {    
     58     while (true)    
     59     {    
     60         //等待非空的缓冲区出现    
     61         WaitForSingleObject( g_hSemaphoreBufferFull, INFINITE );    
     62 
     63         //互斥的访问缓冲区    
     64         EnterCriticalSection(&g_cs);    
     65 
     66         printf("%d号消费者从缓冲池第%d个缓冲区取出数据%d
    
    ",GetCurrentThreadId(), g_j, g_Buffer[g_j]);  
     67         
     68 
     69         if ( g_Buffer[g_j] == END_PRODUCE_NUMBER )   
     70         {    
     71             LeaveCriticalSection(&g_cs);    
     72             break;    
     73         }    
     74 
     75         g_j = ( g_j + 1 ) % BUFFER_SIZE;    
     76         LeaveCriticalSection(&g_cs);    
     77 
     78         Sleep(50); 
     79         
     80         //释放一个数据使empty信号量+1,表示多了一个空位可以生产了
     81         ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL);    
     82     }    
     83     
     84     printf("%d号消费者收到通知,线程结束运行
    
    ", GetCurrentThreadId());    
     85       
     86     return 0;    
     87 }   
     88 
     89 int main()    
     90 {    
     91     printf("    生产者消费者问题   3生产者 1消费者 4缓冲区
    
    ");    
     92 
     93     //初始化临界区 
     94     InitializeCriticalSection(&g_cs);    
     95 
     96     //初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数.    
     97     g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL);    //开始信号量为4个,代表可以生产4个数据
     98     g_hSemaphoreBufferFull  = CreateSemaphore(NULL, 0, 4, NULL);    //开始信号量为0个,代表可以取走0个数据
     99     g_i = 0;
    100     g_j = 0;
    101     memset( g_Buffer, 0, sizeof(g_Buffer) );    
    102    
    103     HANDLE hThread[THREADNUM];    
    104     //生产者线程 3个   
    105     hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);    
    106     hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);    
    107     hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);   
    108     //消费者线程 1个  
    109     hThread[3] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);   
    110 
    111 
    112     //等待线程全部结束后关闭信号量
    113     WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);    
    114     for (int i = 0; i < THREADNUM; i++)    
    115         CloseHandle(hThread[i]);    
    116 
    117     //销毁信号量和关键段    
    118     CloseHandle(g_hSemaphoreBufferEmpty);    
    119     CloseHandle(g_hSemaphoreBufferFull);    
    120     DeleteCriticalSection(&g_cs);    
    121     return 0;    
    122 } 
    View Code

    实验5:写的崩溃,内置一神秘bug,绘制点数如果太多比如超过500绘制一段时间就会未响应,而且绘制期间鼠标变成小圆圈

    猜测是消息循环的问题,因为这是综合了多家代码并进行大量经验主义的修修补补才写成的(实际上完全不懂自己写的是什么)求大神解答为什么会有这种bug

      1 #include <windows.h>
      2 #include <math.h>
      3 #define PI 3.14159265
      4 #define POINTNUM 400
      5 
      6 CRITICAL_SECTION cs;
      7 static TCHAR szAppName[] = TEXT("画圆画方bug版");
      8 static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
      9 
     10 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
     11 {
     12     HWND     hWnd;
     13     MSG      msg;
     14     WNDCLASS wndclass;
     15 
     16     wndclass.style         = CS_HREDRAW | CS_VREDRAW;
     17     wndclass.lpfnWndProc   = WndProc;
     18     wndclass.cbClsExtra    = 0;
     19     wndclass.cbWndExtra    = 0;
     20     wndclass.hInstance     = hInstance;
     21     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
     22     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     23     wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
     24     wndclass.lpszMenuName  = NULL;
     25     wndclass.lpszClassName = szAppName;
     26 
     27     if (!RegisterClass(&wndclass))
     28     {
     29         MessageBox (NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
     30         return 0;
     31     }
     32 
     33     hWnd = CreateWindow(szAppName,            // window class name
     34         szAppName,           // window caption
     35         WS_OVERLAPPEDWINDOW, // window style
     36         CW_USEDEFAULT,       // initial x position
     37         CW_USEDEFAULT,       // initial y position
     38         800,                 // initial x size
     39         600,                 // initial y size
     40         NULL,                // parent window handle
     41         NULL,                // window menu handle
     42         hInstance,           // program instance handle
     43         NULL);               // creation parameters
     44 
     45     ShowWindow(hWnd, iCmdShow);
     46     UpdateWindow(hWnd);
     47 
     48     while (GetMessage(&msg, NULL, 0, 0))
     49     {
     50         TranslateMessage(&msg);
     51         DispatchMessage(&msg);
     52     }
     53 
     54     return msg.wParam;
     55 }
     56 
     57 DWORD WINAPI DrawCircle( LPVOID lpParama )
     58 {
     59     HDC hDC = HDC(lpParama);
     60     int x = 200, y = 250, r = 50;
     61     COLORREF color = RGB(255,0,0);
     62 
     63     int xr, yr;
     64     for (int i=0; i <= POINTNUM; i++)
     65     {
     66         EnterCriticalSection(&cs);
     67 
     68         double rec = ((double)i/POINTNUM*360)*PI/180;
     69         xr = r*cos(rec);
     70         yr = r*sin(rec);
     71 
     72         SetPixel( hDC, x+xr, y+yr, color );
     73 
     74         LeaveCriticalSection(&cs);
     75         Sleep(10);
     76     }
     77     return 0;
     78 }
     79 
     80 DWORD WINAPI DrawRect( LPVOID lpParama )
     81 {
     82     HDC hDC = HDC(lpParama);
     83 
     84     int halfl = 50, halfh =30;
     85     int x = 250, y = 125;
     86     COLORREF color = RGB(255,0,0);
     87 
     88     int average = POINTNUM/4;    
     89 
     90     int xr, yr;
     91     int adx, ady;
     92 
     93     xr = x - halfl; yr = y - halfh;
     94     ady = 0;
     95     for ( int i = 0; i <= average; i++ )
     96     {
     97         EnterCriticalSection(&cs);
     98 
     99         adx = (2*halfl)*i/average;
    100         SetPixel( hDC, x+xr+adx, y+yr+ady, color );
    101 
    102         LeaveCriticalSection(&cs);
    103         Sleep(10);
    104     }
    105 
    106     Sleep(10);
    107     xr = x + halfl; yr = y - halfh;
    108     adx = 0;
    109     for ( int i = 0; i <= average; i++ )
    110     {
    111         EnterCriticalSection(&cs);
    112 
    113         ady = (2*halfh)*i/average;
    114         SetPixel( hDC, x+xr+adx, y+yr+ady, color );
    115 
    116         LeaveCriticalSection(&cs);
    117         Sleep(10);
    118     }
    119 
    120     Sleep(10);
    121     xr = x + halfl; yr = y + halfh;
    122     ady = 0;
    123     for ( int i = 0; i <= average; i++ )
    124     {
    125         EnterCriticalSection(&cs);
    126 
    127         adx = -(2*halfl)*i/average;
    128         SetPixel( hDC, x+xr+adx, y+yr+ady, color );
    129 
    130         LeaveCriticalSection(&cs);
    131         Sleep(10);
    132     }
    133 
    134     Sleep(10);
    135     xr = x -halfl; yr = y + halfh;
    136     adx = 0;
    137     for ( int i = 0; i <= average; i++ )
    138     {
    139         EnterCriticalSection(&cs);
    140 
    141         ady = -(2*halfh)*i/average;
    142         SetPixel( hDC, x+xr+adx, y+yr+ady, color );
    143 
    144         LeaveCriticalSection(&cs);
    145         Sleep(10);
    146     }
    147     return 0;
    148 }
    149 
    150 
    151 static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    152 {
    153     HDC         hDC;
    154     PAINTSTRUCT ps;
    155 
    156     switch (message)
    157     {
    158     case WM_CREATE:
    159         return 0;
    160 
    161     case WM_PAINT:
    162     {
    163         hDC = BeginPaint(hWnd, &ps);
    164 
    165         DWORD ThreadID;
    166         HANDLE hThread[2];
    167         InitializeCriticalSection(&cs);
    168 
    169         hThread[0] = CreateThread( NULL, 0, DrawCircle, (LPVOID)(hDC), 0, &ThreadID );
    170         hThread[1] = CreateThread( NULL, 0, DrawRect, (LPVOID)(hDC), 0, &ThreadID );
    171 
    172         WaitForMultipleObjects( 2, hThread, TRUE, INFINITE );
    173         DeleteCriticalSection(&cs);
    174 
    175         TextOut(hDC, 300, 400, TEXT("绘制完毕!"), 11);
    176     }
    177     EndPaint(hWnd, &ps);
    178     return 0;
    179 
    180     case WM_DESTROY:
    181         PostQuitMessage(0);
    182         return 0 ;
    183     }
    184 
    185     return DefWindowProc (hWnd, message, wParam, lParam);
    186 }
    View Code
  • 相关阅读:
    POJ 1328 Radar Installation
    POJ 1700 Crossing River
    POJ 1700 Crossing River
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3069 Saruman's Army(贪心)
    poj 3069 Saruman's Army(贪心)
    Redis 笔记与总结2 String 类型和 Hash 类型
    数据分析方法有哪些_数据分析方法
    数据分析方法有哪些_数据分析方法
  • 原文地址:https://www.cnblogs.com/chaoswr/p/8865355.html
Copyright © 2011-2022 走看看