Örnek Çoklu İş Parçacığı Kullanan C Programı

Bounce.c, harf a veya A her yazıldığı zaman yeni bir iş parçacığı oluşturan örnek bir çoklu iş parçacığı programıdır. Her yazışma, ekranın çevresinde farklı renkte bir harf döndürmektedir. En fazla 32 iş parçacığı oluşturulabilir. Programın normal sonlandırması, yazıldığında veya Q yazıldığında q gerçekleşir.

Programlar varsayılan olarak çok iş parçacıklı olarak derlenir.

  1. Dosya menüsünde Yeni Proje'yi> seçin.

  2. Yeni proje oluştur iletişim kutusunda C++, Windows ve Konsol etiketleri içeren Konsol Uygulaması şablonunu seçin. Devam etmek için İleri'yi seçin.

  3. Yeni projenizi yapılandırın iletişim kutusunda projeniz için "Bounce" gibi bir ad girin. Devam etmek için Oluştur'u seçin.

  4. Çözüm Gezgini penceresinde projenizin altındaki Kaynak Dosyalar klasörünü açın ve kaynak dosyanızın adını bir .c uzantısına sahip olacak şekilde değiştirin.

  5. Düzenleme penceresinde var olan kaynak kodunu silin ve örnek kodla değiştirin.

  6. Derle menüsünde Çözüm Derle'yi seçin.

  7. Programı hata ayıklayıcıda başlatmak için F5 tuşuna basın.

  1. Dosya menüsünde Yeni Proje'yi> seçin.

  2. Yeni Proje iletişim kutusunda sol bölmede Visual C++ öğesini ve ardından orta bölmede Projeyi Boşalt'ı seçin.

  3. Ad düzenleme kutusuna projeniz için "Bounce" gibi bir ad girin. Boş projeyi oluşturmak için Tamam'ı seçin.

  4. Çözüm Gezgini penceresinde projenizin altındaki Kaynak Dosyalar klasörünü açın ve C kaynak kodunu içeren dosyayı projeye ekleyin.

  5. Derle menüsünde Çözüm Derle komutunu seçerek projeyi derleyin.

  6. Programı hata ayıklayıcıda başlatmak için F5 tuşuna basın.

  7. Yeni bir iş parçacığı oluşturmak için a tuşuna basın. Her iş parçacığı, ekranın çevresinde farklı bir renkteki bir karakteri geri döndürer.

  8. Çıkmak için q tuşuna basın.

  1. Visual Studio araçları komut istemini açın. Bu, yolun derleyiciyi içerecek şekilde ayarlanmasını sağlar.

  2. Programı derleyin ve bağlayın:

    cl bounce.c
    

Örnek

Komut satırında derlemek için bu örneği kopyalayıp .c uzantısına sahip bir kaynak dosyaya kaydedin. IDE'de şablon tarafından oluşturulan herhangi bir kaynak kodunu şu örnekle değiştirin:

// sample_multithread_c_program.c
// compile with: /c
//
//  Bounce - Creates a new thread each time the letter 'a' is typed.
//  Each thread bounces a character of a different color around
//  the screen. All threads are terminated when the letter 'Q' is
//  entered.
//

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

#define MAX_THREADS  32

// The function getrandom returns a random number between
// min and max, which must be in integer range.
#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* pMyID);      // 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 = 0;                // Number of threads started
CONSOLE_SCREEN_BUFFER_INFO csbiInfo; // Console information
COORD   consoleSize;
BOOL    bTrails = FALSE;

HANDLE  hThreads[MAX_THREADS] = { NULL }; // Handles for created threads

int main(void) // Thread One
{
    // Get display screen information & clear the screen.
    hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hConsoleOut, &csbiInfo);
    consoleSize.X = csbiInfo.srWindow.Right;
    consoleSize.Y = csbiInfo.srWindow.Bottom;
    ClearScreen();
    WriteTitle(0);

    // Create the mutexes and reset thread count.
    hScreenMutex = CreateMutexW(NULL, FALSE, NULL);  // Cleared
    hRunMutex = CreateMutexW(NULL, TRUE, NULL);      // Set

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

    // All threads done. Clean up handles.
    if (hScreenMutex) CloseHandle(hScreenMutex);
    if (hRunMutex) CloseHandle(hRunMutex);
    if (hConsoleOut) CloseHandle(hConsoleOut);
}

void ShutDown(void) // Shut down threads
{
    // Tell all threads to die
    ReleaseMutex(hRunMutex);

    while (ThreadNr > 0)
    {
        // Wait for each thread to complete
        WaitForSingleObject(hThreads[--ThreadNr], INFINITE);
    }

    // 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;
            hThreads[ThreadNr] = 
                (HANDLE)_beginthread(BounceProc, 0, (void*)(uintptr_t)ThreadNr);
            WriteTitle(ThreadNr);
        }

        if (tolower(KeyInfo) == 't')
        {
            bTrails = !bTrails;
        }
    } while (tolower(KeyInfo) != 'q');

    ShutDown();
}

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

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

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

    // Set up character & generate color
    // attribute from thread number.
    if (MyID > 16)
        MyCell = (wchar_t)(0x60 + MyID - 16); // lower case
    else
        MyCell = (wchar_t)(0x40 + MyID);      // upper case
    MyAttrib = MyID & 0x0f;   // force black background

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

        if (!bTrails)
        {
            // If we still occupy the old screen position, blank it out.
            ReadConsoleOutputCharacterW(hConsoleOut, &OldCell, 1,
                Old, &Dummy);
            ReadConsoleOutputAttribute(hConsoleOut, &OldAttrib, 1,
                Old, &Dummy);
            if ((OldCell == MyCell) && (OldAttrib == MyAttrib))
                WriteConsoleOutputCharacterW(hConsoleOut, &BlankCell, 1,
                    Old, &Dummy);
        }

        // Draw new character, then clear screen lock
        WriteConsoleOutputCharacterW(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 >= consoleSize.X)
        {
            Delta.X = -Delta.X;
            Beep(400, 50);
        }
        if (Coords.Y < 0 || Coords.Y > consoleSize.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 = 120
    };
    wchar_t    NThreadMsg[sizeOfNThreadMsg] = { L"" };

    swprintf_s(NThreadMsg, sizeOfNThreadMsg,
        L"Threads running: %02d.  Press 'A' "
        L"to start a thread, 'T' to toggle "
        L"trails, 'Q' to quit.", ThreadNum);
    SetConsoleTitleW(NThreadMsg);
}

void ClearScreen(void)
{
    DWORD    dummy = 0;
    COORD    Home = { 0, 0 };
    FillConsoleOutputCharacterW(hConsoleOut, L' ',
        consoleSize.X * consoleSize.Y,
        Home, &dummy);
}

Ayrıca bkz.

C ve Win32 ile Çoklu İş Parçacığı Kullanımı