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
  • 相关阅读:
    Nginx下配置SSL安全协议
    Java嵌套类
    python命名空间与作用域
    Effective Java 4:类和接口
    VIM快捷键(转载)
    Eclipse快捷键
    Effective Java 3:对于所有对象都通用的方法
    Effective Java 1:创建和销毁对象-续
    Effective Java 1:创建和销毁对象
    python文件操作(转载)
  • 原文地址:https://www.cnblogs.com/chaoswr/p/8865355.html
Copyright © 2011-2022 走看看