2012/12/04

分析VC Thread

Source Code來自於微軟Demo,分析是寫給學弟看得,C語言有很多種實現執行緒的方式。

那我找到是這個,就參考底下的範例去分析吧!
依依瞭解C在執行緒的方式以及解決方法,如果你有讀完OS聖經,想必更好懂原因。

哈哈,等你會了老闆一定會愛死你的 哈哈

對了,如果不懂的話下面有我找到的參考資料,慢慢看吧



#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>

#define MAX_THREADS  32
#define getrandom( min, max ) (SHORT)((rand() % (int)(((max) + 1) - \
                               (min))) + (min))

int main( void );                    // Thread 1: main
void KbdFunc( void  );               // Keyboard input, thread dispatch
void BounceProc( void * MyID );      // Threads 2 to n: display
void ClearScreen( void );            // Screen clear
void ShutDown( void );               // Program shutdown
void WriteTitle( int ThreadNum );    // Display title bar information

HANDLE  hConsoleOut;                 // Handle to the console
HANDLE  hRunMutex;                   // "Keep Running" mutex
HANDLE  hScreenMutex;                // "Screen update" mutex
int     ThreadNr;                    // Number of threads started
CONSOLE_SCREEN_BUFFER_INFO csbiInfo; // Console information

int main() // Thread One
{
    // Get display screen information & clear the screen.
    hConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );//取得使用者輸入的字元
    GetConsoleScreenBufferInfo( hConsoleOut, &csbiInfo );    //取得終端機的介面資訊
    ClearScreen();    //清除螢幕
    WriteTitle( 0 );    //寫入標題

    // Create the mutexes and reset thread count.
    hScreenMutex = CreateMutex( NULL, FALSE, NULL );  // 清除執行緒同步
    hRunMutex = CreateMutex( NULL, TRUE, NULL );      // 設定所有執行緒同步
    ThreadNr = 0;

    // Start waiting for keyboard input to dispatch threads or exit.
    KbdFunc();

    // All threads done. Clean up handles.
    CloseHandle( hScreenMutex );    //釋放資源
    CloseHandle( hRunMutex );
    CloseHandle( hConsoleOut );
}

void ShutDown( void ) // Shut down threads
{
    while ( ThreadNr > 0 )
    {
        // Tell thread to die and record its death.
        ReleaseMutex( hRunMutex );    //釋放執行緒
        ThreadNr--;
    }

    // Clean up display when done
    WaitForSingleObject( hScreenMutex, INFINITE );
    ClearScreen();
}

void KbdFunc( void ) // Dispatch and count threads.
{
    int         KeyInfo;

    do
    {
        KeyInfo = _getch();    //取得輸入字元
        if ( tolower( KeyInfo ) == 'a' &&    //
             ThreadNr < MAX_THREADS )
        {
            ThreadNr++;
            _beginthread( BounceProc, 0, &ThreadNr );    //啟動執行緒
            WriteTitle( ThreadNr );    //
        }
    } while( tolower( KeyInfo ) != 'q' );

    ShutDown();
}

void BounceProc( void *pMyID )
{
    char    MyCell, OldCell;
    WORD    MyAttrib, OldAttrib;
    char    BlankCell = 0x20;
    COORD   Coords, Delta;
    COORD   Old = {0,0};
    DWORD   Dummy;
    char    *MyID = (char*)pMyID;

    // Generate update increments and initial
    // display coordinates.
    srand( (unsigned int) *MyID * 3 );

    Coords.X = getrandom( 0, csbiInfo.dwSize.X - 1 );
    Coords.Y = getrandom( 0, csbiInfo.dwSize.Y - 1 );
    Delta.X = getrandom( -3, 3 );
    Delta.Y = getrandom( -3, 3 );

    // Set up "happy face" & generate color
    // attribute from thread number.
    if( *MyID > 16)
        MyCell = 0x01;          // outline face
    else
        MyCell = 0x02;          // solid face
    MyAttrib =  *MyID & 0x0F;   // force black background

    do
    {
        // Wait for display to be available, then lock it.
        WaitForSingleObject( hScreenMutex, INFINITE );

        // If we still occupy the old screen position, blank it out.
        ReadConsoleOutputCharacter( hConsoleOut, &OldCell, 1,
                                    Old, &Dummy );
        ReadConsoleOutputAttribute( hConsoleOut, &OldAttrib, 1,
                                    Old, &Dummy );
        if (( OldCell == MyCell ) && (OldAttrib == MyAttrib))
            WriteConsoleOutputCharacter( hConsoleOut, &BlankCell, 1,
                                         Old, &Dummy );

        // Draw new face, then clear screen lock
        WriteConsoleOutputCharacter( hConsoleOut, &MyCell, 1,
                                     Coords, &Dummy );
        WriteConsoleOutputAttribute( hConsoleOut, &MyAttrib, 1,
                                     Coords, &Dummy );
        ReleaseMutex( hScreenMutex );

        // Increment the coordinates for next placement of the block.
        Old.X = Coords.X;
        Old.Y = Coords.Y;
        Coords.X += Delta.X;
        Coords.Y += Delta.Y;

        // If we are about to go off the screen, reverse direction
        if( Coords.X < 0 || Coords.X >= csbiInfo.dwSize.X )
        {
            Delta.X = -Delta.X;
            Beep( 400, 50 );
        }
        if( Coords.Y < 0 || Coords.Y > csbiInfo.dwSize.Y )
        {
            Delta.Y = -Delta.Y;
            Beep( 600, 50 );
        }
    }
    // Repeat while RunMutex is still taken.
    while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT );
}

void WriteTitle( int ThreadNum )
{
    enum {
        sizeOfNThreadMsg = 80
    };
    char    NThreadMsg[sizeOfNThreadMsg];

    sprintf_s( NThreadMsg, sizeOfNThreadMsg,
               "Threads running: %02d.  Press 'A' "
               "to start a thread,'Q' to quit.", ThreadNum );
    SetConsoleTitle( NThreadMsg );
}

void ClearScreen( void )
{
    DWORD    dummy;
    COORD    Home = { 0, 0 };    //控制台座標型態
    FillConsoleOutputCharacter( hConsoleOut, ' ',
                                csbiInfo.dwSize.X * csbiInfo.dwSize.Y,
                                Home, &dummy );    //設定終端機初始字元
}

資料參考:
http://msdn.microsoft.com/zh-tw/library/esszf9hw(v=vs.80).aspx
http://slimemeteor.blogspot.tw/2010/10/sprintf-and-snprintf-and-buffer.html
http://baike.baidu.com/view/2666640.htm
http://zhidao.baidu.com/question/243419995.html
http://www.dreamincode.net/forums/topic/153240-console-cursor-coordinates/
http://www.programmer-club.com/showSameTitleN/c/28156.html
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682663(v=vs.85).aspx
http://www.cppblog.com/finehai/archive/2012/11/24/90746.html
http://blog.csdn.net/laura0502/article/details/3838732
http://hs.hosp.ncku.edu.tw/~cww/htmapi73.htm
http://bbs.csdn.net/topics/21693
http://www.njustjx.cn/thread-239-1-1.html
http://msdn.microsoft.com/zh-tw/library/kdzttdcb(v=vs.80).aspx
http://msdn.microsoft.com/zh-tw/library/system.threading.mutex.releasemutex(v=vs.80).aspx
http://msdn.microsoft.com/zh-tw/library/windows/desktop/ms685066(v=vs.85).aspx
http://blog.sina.com.cn/s/blog_630e168d0100tfnv.html
http://www.360doc.com/content/10/0512/09/1072296_27178529.shtml
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684969(v=vs.85).aspx
http://hi.baidu.com/console_app/item/0e5e7ad689737111e1f46f00
http://tlcheng.twbbs.org/TLCheng/WinAPI/winapi.asp?action=FunName&FunName=ReadConsoleOutputCharacter
http://bbs.csdn.net/topics/300073601
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687407(v=vs.85).aspx
http://zhidao.baidu.com/question/313723405.html
http://hi.baidu.com/ncudlz/item/341e0df034030ecd521c262e
http://msdn.microsoft.com/zh-tw/library/windows/desktop/ms724211(v=vs.85).aspx