sobota, 3 września 2011

C/C++ - mały przykład pracy z wątkami

Pojawiła się okazja udziału w ciekawym projekcie programistycznym. Niestety wiodącym językiem w jakim to rozwiązanie powstaje jest niewdzięczny C++. Wiadomo, język programowania to tylko narzędzie. Muszę jednak udowodnić sobie, że jeszcze pamiętam jak tego narzędzia się używa i że jestem w stanie szybko się przełączyć na jego używanie. Jedno z istotniejszych zagadnień w programowaniu aktualnie to wątki. Zamieszczam bardzo mały przykład aplikacji wykorzystującej wątki napisanej w C/C++.

Aplikacja z założenia jest niezwykle prosta. Wystarczy samo tworzenie wątku, wykonanie operacji i zakończenie pracy. Nie najgorszym przykładem będzie więc aplikacja uruchamiająca pewną liczbę wątków, przekazująca do każdego identyfikator liczbowy. Każdy wątek będzie miał za zadanie wyłącznie się przedstawić i zakończy swoje działanie.

#include <iostream>
#include <stdlib.h>
#include <process.h>
#define MAXTHREAD 10

using namespace std;

void Thread(void* pParams)
{
    int* num = static_cast<int*>(pParams);
    cout << "My id is: " << *num << endl;
}   

int main(int argc, char *argv[])
{
    for(int i=0;i < maxthread;i++)
    {
        cout << "Starting thread " << i << endl;
        _beginthread(Thread,0,(void*)&i);
    }   
   
    system("PAUSE");
    return 0;
}

Kod ma niestety pewne wady. Tak po szybkiej analizie, to dwie wady. Obie wynikają z rywalizacji o zasoby. Jednym zasobem jest ekran. Zarówno wątek główny jak i każdy nowy wątek wymaga dostępu do ekranu przez co komunikaty na ekranie się ze sobą przeplatają. To nawet mało powiedziane. Same słowa się ze sobą przeplatają, a nie całe komunikaty.

Drugim problemem jest przekazywanie argumentu do wątku przez referencję. Celowo korzystam dalej również z adresu, a nie kopii wartości. Dzięki temu widać, że wątek potrafi podać niepoprawną wartość identyfikatora. Przynajmniej wtedy gdy uda się połapać gdzie są czyje komunikaty na ekranie.

Czytaj też:

1 komentarz:

  1. Próbuję uruchomić wątek w Visual Studio C++ 2010. Podczas kompilacji w wierszu:
    _beginthread(Thread,0,0);
    jest sygnalizowany poniższy błąd:
    error C3867: 'CVirtualTruckDlg::Thread': function call missing argument list; use '&CVirtualTruckDlg::Thread' to create a pointer to member

    Proszę o pomoc, jak się go pozbyć.
    Piotr

    OdpowiedzUsuń