Jarosław Rybski

Jarosław Rybski Programista
C/C++/Python

Temat: Zapewnić istnienie określonej liczby wątkow

Witam,

Mam problem z pewnym zadaniem.
Aplikacja łączy się z serwerem poprzez protokół TCP/IP.
Zawiera wątki. Zadaniem wątku jest wysłanie do serwera ciągu znaków np: 'x1', 'x2', 'x3' ... 'x9999' - oraz otrzymanie odpowiedzi w stylu wszystko ok lub błąd;

Chciałbym aby jednocześnie było uruchomionych około 100 wątków w porywach +- 10. Jak wiadomo CreateThread utworzy mi 10 tys wątków w niespełna kilka, kilkanaście sekund ale wątki nie wysyłają tak szybko danych. Każdy wątek potrzebuje kilku sekund na wykonanie zadania.

Zrobiłem tak:

#define MAX_THREADS 10000
HANDLE hT[MAX_THREADS];
DWORD dwId;
for(int i = 0; i < MAX_THREADS; i++)
{
pthread_mutex_lock(&mutex);
if (iAktualnaLiczbaWatkow < 100)
{
hT[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMain, (LPVOID)i, 0, &dwId);
if (hT[i]==NULL) i--;
}
else
{
i--;
}
pthread_mutex_unlock(&mutex);
}
WaitForMultipleObjects(MAX_THREADS, hT, TRUE, INFINITE);
for(int i = 0; i < MAX_THREADS; i++)
{
CloseHandle(hT[i]);
}


ale niestety nie działa po mojej myśli. Wbrew oczekiwaniom posiadam od 150 do 200 wątków przez około jedną minutę a przy wzroście obciążenia aktualna liczba wątków spada do 120. Bardzo duży rozrzut niestety.

Funkcja uruchamiana jako watek zwiększa licznik oraz zmniejsza go gdy watek kończy się.


DWORD ThreadMain( LPVOID iParam )
{
pthread_mutex_lock(&mutex);
iAktualnaLiczbaWatkow++;
pthread_mutex_unlock(&mutex);
int icnt = (int)iParam;
...
...
...
closesocket(sClient);
pthread_mutex_lock(&mutex);
iAktualnaLiczbaWatkow--;
pthread_mutex_unlock(&mutex);
return 1;
}


Ma ktoś z Was ciekawy sposób na zapewnienie istnienia określonej liczby wątków przez cały okres działania programu.
Jakub L.

Jakub L. Programista

Temat: Zapewnić istnienie określonej liczby wątkow

Jeżeli mutex jest ten sam, to na moje oko wątek inkrementuje iAktualnaLiczbaWatkow dośc późno i wszystko zależy od przydziału czasu.
Ja bym dał kontrolowanie liczby wątków w pierwszym kodzie - kontrolerze a wątkom pozwolił robić swoje zamiast się pilnować i liczyć.

Temat: Zapewnić istnienie określonej liczby wątkow

jesli chcesz miec w danej chwili n watkow to:
1. uruchamiasz n watkow,
2. dajesz im zajecie, by przypadkiem sie nie skonczyly.

jesli n jest duze (kilkaset lub wiecej) moga wejsc zabawy ze stosem i inne ustawienia (zeby 1 watek mial mniej zasobow, bo wysycisz zasoby dla aplikacji).
ale to zalezy od konfiguracji systemu, na ktorym uruchamiasz proces.
Jarosław Rybski

Jarosław Rybski Programista
C/C++/Python

Temat: Zapewnić istnienie określonej liczby wątkow

Tak racja - trzeba liczyć ilość utworzonych wątków w pętli for


for(int i = 0; i < MAX_THREADS; i++)
{ pthread_mutex_lock(&mutex);
if (iAktualnaLiczbaWatkow < 100)
{
hT[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMain, (LPVOID)i, 0, &dwId);
if (hT[i]==NULL) i--;
else iAktualnaLiczbaWatkow++;
}
else
{
i--;
}
pthread_mutex_unlock(&mutex);
Sleep(10);
}


Obecnie menadżer zadań pokazuje od 99 do 101 wątków a więc wg. założeń.

Pozdrawiam.
Marek Dąbek

Marek Dąbek Software Engineer,
Intel Technology
Poland

Temat: Zapewnić istnienie określonej liczby wątkow

Jarosław Rybski:
Tak racja - trzeba liczyć ilość utworzonych wątków w pętli for


for(int i = 0; i < MAX_THREADS; i++)[/quote]> { pthread_mutex_lock(&mutex);[quote] if (iAktualnaLiczbaWatkow < 100)[/quote]> {[quote] hT[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMain, (LPVOID)i, 0, &dwId);
if (hT[i]==NULL) i--;
else iAktualnaLiczbaWatkow++;
}
else
{
i--;
}
pthread_mutex_unlock(&mutex);
Sleep(10);
}


Z innej beczki... dlaczego pobierasz mutex przy tworzeniu wątków? Czy po to, żeby sprawdzić iAktualnaLiczbaWatkow < 100?
Dobrą praktyką jest stosowanie minimalnej sekcji krytycznej i nie włączanie do niej kodu, którego działania nie znamy (np. CreateThread).Marek Dąbek edytował(a) ten post dnia 28.04.10 o godzinie 21:05
Jarosław Rybski

Jarosław Rybski Programista
C/C++/Python

Temat: Zapewnić istnienie określonej liczby wątkow

Słuszne pytanie- można to było i zupełnie inaczej zrobić (rozwiązanie na szybko w parę minut zrealizowane) ale linijka pod CreateThread mam inkrementacje licznika pracujących wątków. Dekrementacja tej samej zmiennej jest podczas kończenia kodu wątka - dlatego zdecydowałem się na mutexa.
Ponadto jest Sleep - a więc czas na przełączenie wykonywanego kodu.
Adam Woźniak

Adam Woźniak software architect
and developer

Temat: Zapewnić istnienie określonej liczby wątkow

Jarosław Rybski:
Tak racja - trzeba liczyć ilość utworzonych wątków w pętli for


for(int i = 0; i < MAX_THREADS; i++)[/quote]> { pthread_mutex_lock(&mutex);[quote] if (iAktualnaLiczbaWatkow < 100)[/quote]> {[quote] hT[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMain, (LPVOID)i, 0, &dwId);
if (hT[i]==NULL) i--;
else iAktualnaLiczbaWatkow++;
}
else
{
i--;
}
pthread_mutex_unlock(&mutex);
Sleep(10);
}


Obecnie menadżer zadań pokazuje od 99 do 101 wątków a więc wg. założeń.

Średnio mi się podoba ten algorytm.
Sleep słaby jest w tym wypadku. Na Sleep-ie będziesz miał opóźnienia. Tzn. o tym, że jakiś z wątków roboczych się zakończył będziesz dowiadywał się z opóźnieniem, czyli nie dobrze.

Generalnie, to na Twoim miejscu, zamiast używać Sleep, to w głównym wątku, kiedy wiadomo, że wszystkie 100 wątków jest odpalonych, to wstrzymałbym pracę głównego wątku na WaitForMultipleObjects w oczekiwaniu na zakończenie się jakiegoś wątku roboczego.

Pozdrawiam, Adam Woźniak
L P

L P podskala.net

Temat: Zapewnić istnienie określonej liczby wątkow

Proponuje wyrzucić Sleep (ms) i spróbować zrobić to przy użyciu condition variables. Dodatkowo jak zapewne Adam juz zauwazyl podnoszenie i opuszczanie sem./mutexow warto robic w tym samym bloku funkcyjnym.

http://en.wikipedia.org/wiki/Monitor_%28synchronizatio...

Temat: Zapewnić istnienie określonej liczby wątkow

Zamiast zabawy w mutexy przy liczniku sugeruje uzyc operacji atomowych:

Windows:
http://msdn.microsoft.com/en-us/library/ms683614%28VS....

Unix:
http://publib.boulder.ibm.com/infocenter/aix/v6r1/inde...

Następna dyskusja:

rząd liczby [C]




Wyślij zaproszenie do