CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - STL list i wątki wykonywanie operacji na liscie

STL list i wątki wykonywanie operacji na liscie

dział ogólny

STL list i wątki wykonywanie operacji na liscie

Postprzez Darek_C++ » czwartek, 16 grudnia 2010, 20:20

Witam ponownie z kolejnym problemem :)
Program ma za zadanie wykonywanie operacji np na adresach www zawartych w TListViev aż do poprawnego sprawdzenia wszystkich adresów.
Operacje wykonywane są w watkach których naraz możne być np 5 operacja w wątku może się nie powieść należy ją powtarzać , aż wszystkie adresy zostaną poprawnie sprawdzone. Poprawność operacji true, false w tym testowym programie jest symulowana losowaniem.
Algorytm jaki wymyśliłem jest następujący. Do typu list STL ładuję nr z ListView i przekazuje do wątku wskaźnik do tej listy.
W zsynchronizowanej metodzie wątku PobierzStart(); usuwam dany element [liczbę] z listy tak by kolejny wątek nie wywołał tej samego adresu wywołuję operacje w Execute() i PobierzStop(); . W PobierzStop(); symuluje poprawność wykonania operacji jeśli jest poprawna nic nie robię z list jeśli nie wstawiam do niej z powrotem nr do ponownego sprawdzenia.

Cały kod główny formularza:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{

        Timer1->Interval = 100;
        Timer1->Enabled  = false;

        // Wypelniam testowo ListViev
        for(int ii = 0; ii < 50; ii++)
        {
                TListItem * ElementListy = ListView1->Items->Add();
                ElementListy->Caption = "Adres nr: "+(String) ii;;
                ElementListy->SubItems->Add("---");

        }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MyOnTerminate(TObject *Sender)
{
        this->ileWatkow --;
        StatusBar1->Panels->Items[1]->Text="Aktywnych wątków: "+IntToStr(this->ileWatkow);
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        myList.clear();
        for(int ii = 0; ii < 50; ii++)
        {
                myList.push_back(ii);
                ListView1->Items->Item[ii]->SubItems->Strings[0] = "---";
        }
        // Uruchamiam timer ktory odpala watki
        Timer1->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
        if(this->ileWatkow < 5)
        {
                if(myList.size() == 0)
                {
                        Timer1->Enabled = false ;
                        StatusBar1->Panels->Items[1]->Text="KONIEC";
                        StatusBar1->Panels->Items[0]->Text="Do sprawdzenia "+IntToStr(myList.size());
                }
                else
                {
                        Watek = new MyWatek(true);
                        Watek->ListView1 = ListView1;
                        Watek->pointerList = &myList;
                        Watek->OnTerminate = MyOnTerminate;
                        Watek->Resume();
                        this->ileWatkow++;
                        StatusBar1->Panels->Items[0]->Text="Do sprawdzenia "+IntToStr(myList.size());
                        StatusBar1->Panels->Items[1]->Text="Aktywnych wątków: "+IntToStr(this->ileWatkow);
                }
        }
}
//---------------------------------------------------------------------------
 


Kod wątku:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#include <math.hpp>
#pragma hdrstop

#include "UnitMyWatek.h"
#pragma package(smart_init)

//---------------------------------------------------------------------------

__fastcall MyWatek::MyWatek(bool CreateSuspended)
        : TThread(CreateSuspended)
{
        FreeOnTerminate = true;
        this->tuNrNaList = 0;

}

void __fastcall MyWatek::PobierzStart()
{
        // pobieram wartosc pierwszego elementu z listy i go usuwam
        // po to by inny ruszajacy watek nie pobral tej samej wartosci
        this->tuNrNaList = pointerList->front();
        pointerList->remove(this->tuNrNaList);
        ListView1->Items->Item[this->tuNrNaList]->SubItems->Strings[0] = "Start...";
}

//---------------------------------------------------------------------------
void __fastcall MyWatek::Execute()
{
        Synchronize(&PobierzStart);
        // Jakas czasowa operacja
        Sleep(RandomRange(100, 2000));
        Synchronize(&PobierzStop);
}
//---------------------------------------------------------------------------
void __fastcall MyWatek::PobierzStop()
{
        // symuluje losowa poprawnosc operacji
        randomize();
        if(RandomRange(1, 10) >= 5)
        {
                ListView1->Items->Item[this->tuNrNaList]->SubItems->Strings[0] = "Wynik Dobry";
        }
        else
        {
                // operacja nie udana wiec trzeba ja powrorzyc w tym celu spowrotem
                // dodaje wartosc do  listy do ponownego wywolania w kolejnym przebiegu
                pointerList->push_back(this->tuNrNaList);
                ListView1->Items->Item[this->tuNrNaList]->SubItems->Strings[0] = "Wynik Zly";
        }
}

Cały projekt w załączniku.

Problem jest taki, że bardzo często w TlstViev mam Wynik Zly, a z założenie operacja miała byc tak długo wykonywana, aż wszystkie wyniki będą poprawne "Wynik Dobry". Proszę o pomoc w poprawieniu - [wskazaniu błędu] tego kodu by działał zgodnie z oczekiwaniem.
--------
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: STL list i wątki wykonywanie operacji na liscie

Postprzez Cyfrowy Baron » piątek, 17 grudnia 2010, 09:56

Mała uwaga odnośnie generatora liczb. Funkcja randomize uruchamia generator liczb, generator działa tak długo jak długo działa program, więc generator uruchamiamy tylko raz np. po uruchomieniu programu.
Dla funkcji RandomRange właściwym generatorem jest funkcja Randomize (pisane z wielkiej litery) i tego generatora należy użyć. Powszechnym błędem jest założenie, że wystarczy uruchomić jakikolwiek generator by losowanie działało. To nieprawda! Masz dwa rodzaje generatorów. randomize (pisany z małej litery) i jest on właściwym dla funkcji losujących również pisanych z małej litery, np. dla funkcji random. Generator Randomize (pisany z wielkiej litery) jest właściwy dla funkcji losujących pisanych z wielkiej litery, np. Random.

O tym możesz poczytać w plikach pomocy.



Z pliku pomocy dla funkcji Randomize:

Do not combine the call to Randomize in a loop with calls to the Random function. Typically, Randomize is called only once, before all calls to Random.


Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: STL list i wątki wykonywanie operacji na liscie

Postprzez Darek_C++ » piątek, 17 grudnia 2010, 10:23

OK, teraz będę wiedział jak prawidłowo używać funkcji losujących liczby jednak to nie jest przyczyną nieprawidłowego działania programu :(
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: STL list i wątki wykonywanie operacji na liscie

Postprzez polymorphism » piątek, 17 grudnia 2010, 13:11

Prawdopodobnie wynika to z tego, że miedzy wywołaniem PobierzStart a wywołaniem PobierzStop warunek:
KOD cpp:     UKRYJ  
if(myList.size() == 0) // do sprawdzania, czy lista jest pusta, masz metodę 'empty'

może być prawdziwy, a co za tym idzie całość zostanie przerwana. Zrób dwie listy: jedna z operacjami do zrobienia, a druga z operacjami aktualnie wykonywanymi. I wtedy jeśli obie listy będą puste, możesz śmiało założyć, że zadanie zostało wykonane.
KOD cpp:     UKRYJ  
this->tuNrNaList = pointerList->front();
pointerList->remove(this->tuNrNaList);

Do usuwania z frontu masz pop_front. remove nieco inaczej działa niż to się wydaje.
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Darek_C++
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: STL list i wątki wykonywanie operacji na liscie

Postprzez Darek_C++ » piątek, 17 grudnia 2010, 14:21

Prawdopodobnie wynika to z tego, że miedzy wywołaniem PobierzStart a wywołaniem PobierzStop warunek:


Dokładnie to okazało się problemem i udało mi się go już wczoraj rozwiązać , ale nie odpisywałem bo mam kolejny problem tym razem z formularzem DLL i watkami bryyyyy który zaraz opiszę w następnym topicku .
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: STL list i wątki wykonywanie operacji na liscie

Postprzez polymorphism » piątek, 17 grudnia 2010, 14:36

Hmm, jak to wczoraj, jeśli dzisiaj napisałeś: '(...) jednak to nie jest przyczyną nieprawidłowego działania programu'?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: STL list i wątki wykonywanie operacji na liscie

Postprzez Darek_C++ » piątek, 17 grudnia 2010, 14:42

@jednak to nie jest przyczyną
Tyczyło się tego co napisał CB...

Wczoraj napisałem post jak jeszcze nie znalazłem błędu. Błąd znalazłem też wczoraj wieczorem, ale już o tym wczoraj ani dzisiaj nie pisałem, bo byłem ciekaw czy ktoś z Was podsunie może całkiem inne rozwiązanie na tą operację :) .
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: STL list i wątki wykonywanie operacji na liscie

Postprzez polymorphism » piątek, 17 grudnia 2010, 14:52

Złe podejście, nie szanujesz czasu innych. Na przyszłość jeśli chcesz mieć inne propozycje, po prostu o nie zapytaj. Jeśli sam rozwiązałeś problem, to napisz to (wraz opisem przyczyny).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: STL list i wątki wykonywanie operacji na liscie

Postprzez Darek_C++ » piątek, 17 grudnia 2010, 14:58

Szanuje Wasz czas, ale napotkałem problem opisany w viewtopic.php?f=2&t=1179 który pojawił się w dlaszej kolejności i tym się teraz cały czas zajmowałem.

Tam tez w kodzie jest rozwiązanie problemu z tego topicku.
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 5 gości