Zaawansowane: Czy uzywac Synchronize (watki)

0

Witam

Mam pewien problem, mam aplikacje w której co 10 ms wykonywany jest wątek(Thread) wysyłania, oczywiscie wątku jest FreeOnTerm.. na true, ale problem w tym ze czasami program niespodziewanie sie konczy poprstu słychac komunikat błędu i nagle program sie zamyka, przypuśćmy róznie sie to zdarza czasmi aplikacja moze wyslac 2 dni i nic a czasem 3 godizny i sie wywala, komunikatu nie widac tlyko komunika bledu słychac i aplikacja znika...

W watku mam pare pętli odwołuja sie one do globalenj zmiennej jest tam odczyt i zapis do TSTringList, oraz Odwołanie do komponentu TServerSocket, ale tylko wysłanie buforu... jest tez operacja odczytu pliku BlockRead..

Czy może byc to przyczyna ze kilka wątków próbuje wysłać w jednym czasie bufer przez TServerScoket?

Nie mam tego jak stwierdzić bo musiałbym robic testy z 4 miesiące az będą bledy wyskakiwać;/

Wiec czego to moze byc przyczyną ?
Tego ze wątki próbują wykorzystać w jednym czasie TServerSocket do przeslania buforu ? a może tego ze odczytują i zapisują na zmiennej globalnej TSringLIst zawartą w unicie1 (glownym)?
I czy użycie Synchronize pomoże ? jak to wykonac synchronize przed wysłani czy po wysłaniu buforu?
np.
forma1.serversocket.connection[i].sendBuf(...);
Synchronize(SetProprties);

a moze wstawic Synchronize(SetProprties); na samym poczatku wątku ?

hm..
Ktoś jest w stanie pomóc ?
Jak zbudowac dobra synchronize ?
POZDRAWIAM i dziękuje

0

Prawdopodobnie właśnie chodzi o Synchronize. Zarówno dostęp do TStringList, jak i TServerSocket, a także dowolnych innych komponentów, używanych w innym wątku, należy realizować przez Synchronize lub analogiczne mechanizmy (mutexy, itp).

Nie masz go umieścić przed odwołaniem czy po odwołaniu, ale odwołanie masz zrobić w ramach procedury podawanej Synchronize jako parametr.

0
Szczawik napisał(a)

Prawdopodobnie właśnie chodzi o Synchronize. Zarówno dostęp do TStringList, jak i TServerSocket, a także dowolnych innych komponentów, używanych w innym wątku, należy realizować przez Synchronize lub analogiczne mechanizmy (mutexy, itp).

Nie masz go umieścić przed odwołaniem czy po odwołaniu, ale odwołanie masz zrobić w ramach procedury podawanej Synchronize jako parametr.

no fakt, sory zamieszalem :P

ale TStringList nie jest <ort>komponętem </ort>to jest zmienna, bardziej bym stawiał na TServerSocket
i musilbym to wykonywac tak
Synchronize(Wyslij_bufer(bufer,nr_<ort>polonczenia</ort>,czas));

Można przetrzymywac w synchronize dodatkowe parametry ? bo musi to byc przekazane żeby to zadziałało ;/ i jak to bedzie z wywołanymi watkami które oczekuj jak sie ich namnoży zawiele w kolejce:D?

0

Czy wykonanie tego watku trwa dlugo?
Czy program robi cos w glownym watku?

Moze lepiej zrobic tylko jeden dodatkowy watek,
i w nim stworzyc dynamicznie serversocket, i po kolei
wysylac to co masz do wyslania?

0
nikus napisał(a)
Szczawik napisał(a)

Prawdopodobnie właśnie chodzi o Synchronize. Zarówno dostęp do TStringList, jak i TServerSocket, a także dowolnych innych komponentów, używanych w innym wątku, należy realizować przez Synchronize lub analogiczne mechanizmy (mutexy, itp).

Nie masz go umieścić przed odwołaniem czy po odwołaniu, ale odwołanie masz zrobić w ramach procedury podawanej Synchronize jako parametr.

no fakt, sory zamieszalem :P

ale TStringList nie jest <ort>komponętem </ort>to jest zmienna, bardziej bym stawiał na TServerSocket
i musilbym to wykonywac tak
Synchronize(Wyslij_bufer(bufer,nr_polonczenia,czas));

Można przetrzymywac w synchronize dodatkowe parametry ? bo musi to byc przekazane żeby to zadziałało ;/ i jak to bedzie z wywołanymi watkami które oczekuj jak sie ich namnoży zawiele w kolejce:D?

nie za bardzo (jak sobie to wyobrażasz ze server ma sie <ort>lonczyc </ort>z klientem :D hehe :) ), nie moge tworzyć dynamicznie TserverSocket, a od czasu wykonania wątku (co 10 ms) zależy częstotliwość aktualizacji statystyk.

Zauważyłem ze z sychronize chodzi wolniej ... zrobiłem sobie mały tescik

wystarczy wywoływać wątek w odstepach 130 ms ... tragedia ;/

moze cos zle robie z tym synchronize ?

type
  Ttest1 = class(TThread)
  private
    { Private declarations }
    gx:string;
    ix:integer;
    procedure maluj;
  protected
    procedure Execute; override;
  end;

implementation

{ Important: Methods and properties of objects in VCL or CLX can only be used
  in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure Ttest1.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ Ttest1 }

procedure Ttest1.Execute;
var
i:integer;
begin
FreeOnTerminate:=true;
for i:=0 to 50000 do
  begin
  //sleep(100);
  gx:=IntToStr(i);
  ix:=i;
  synchronize(maluj);
  end;
end;

procedure TTest1.maluj;
begin
form1.Label1.Caption:=gx+' int:'+IntToStr(ix);
end;

na tym tescie widac jak zachowuje sie forma główna ... no <ort>naszczescie </ort>chodzi o grafike wiec przy wysyłaniu bufera przez TserverSocket nie powino byc problemu... ale dla pewnosci napiscie co o tym sadzicie..

pozdrawiam

0

Synchronize uzywamy dla metod ktore operuja na komponentach wizualnych np.


TThread::OdswiezDane()
{
   Label1->Text = "ala ma kota";
};

Jest to spowodowane tym ze operacje na komponentach wizualnych MUSZA byc zsynchronizeowane z glowna petla komunikatow windowsa co wlasnie zapewnia Synchronize(); Jesli tego nie zrobisz beda wyloty.

poza tym Sleep() w watku tez musi byc wywolywany przez Synchronize(); o ile dobrze pamietam (chyba).

0
EgonOlsen napisał(a)

Synchronize uzywamy dla metod ktore operuja na komponentach wizualnych np.


TThread::OdswiezDane()
{
   Label1->Text = "ala ma kota";
};

Jest to spowodowane tym ze operacje na komponentach wizualnych MUSZA byc zsynchronizeowane z glowna petla komunikatow windowsa co wlasnie zapewnia Synchronize(); Jesli tego nie zrobisz beda wyloty.

poza tym Sleep() w watku tez musi byc wywolywany przez Synchronize(); o ile dobrze pamietam (chyba).

no właśnie o to mi chodziło by ktoś upewnił mnie w moim przekonaniu co do potrzeby użycia synchronize dla zmiennej TStringList, i serverSocket przecież to nie sa składniki wizualne.

Więc teraz mam mały mętlik w głowie co może byc dokładną przyczyną wywalania programu, "natłok" wątków odpada bo są dobrze zarządzane... jedyne o to TServerSocket wywoływany w tym samym momencie przez kilka kopi wątku...

hm... ?

0

Słyszałeś o czymś takim jak debugger?

Poza debuggerem wbudowanym w środowisko możesz skorzystać z zewnętrznych narzędzi, które w sposób łopatologiczny wyświetlą np. nie usunięte obiekty i inne błędy w kodzie, które mogą przyczynić się do błędnego działania programu lub jego zamykania/zawieszania się.

0
AdamPL napisał(a)

Słyszałeś o czymś takim jak debugger?

Poza debuggerem wbudowanym w środowisko możesz skorzystać z zewnętrznych narzędzi, które w sposób łopatologiczny wyświetlą np. nie usunięte obiekty i inne błędy w kodzie, które mogą przyczynić się do błędnego działania programu lub jego zamykania/zawieszania się.

heh a ty o ludzkim oku ?
Deb przemawia ze wszystko jest ok, 0 błedów... a druga sprawa ze chyba nieczytales całego wątku chodzi o to ze chodzi ale czasem np. może sie to zdarzyć za 3 tygodnie badz 2 lata ze program sie wywala i nie wiem dlaczego może następnym razem przed wypowiedzią przeczytaj cały temat

pozdrawiam

0

Nie wiem czemu się oburzasz, starałem się pomóc ale jak widać nie każdy potrafi to docenić. 0 błędów może pokazywać kompilator, a nie debugger.

Dowiedz się co to jest debugger. Rozejrzyj się również za innymi, prostszymi narzędziami do debuggowania kodu Delphi, które w parę chwil wskażą każdy obiekt którego zapomniało się zwolnić itp. to może znacznie skrócić poszukiwanie błędu w programie. Poza tym pamiętaj, że Delphi nie obsługuje wyjątków w wątkach, tj. nie wyświetla komunikatu o błędzie.

0

przepraszam jezeli poczułeś sie obrażony, ale nie to miałem na myśli. Wywnioskowałem z twojej wypowiedzi ze to ty próbujesz mnie osmieszyć. Ale ok to się ort!, wazne są chęci ale na przyszłość troche szacunku do innych osób, może ja mam takie uczucie ale <ort>zaczoles </ort>tak posta jakbyś chciał mnie poniżyć...

A wracajac do tematu wiem co to szukanie błedów linijka po linijce lub funkcja po funkcji, ale własnie chodzi o to że <ort>niezawsze </ort>to wypala jak młwilem błąd pojawia się dość rzadko wręcz sporadycznie dlatego proszeo pomoc ludzi a nie narzedzie jakim jest Delphi

pozdrawiam

0

Chyba znalazłem przyczynę ale wole spytać o to jeszcze Was w wątku Thread do uses dodany mam unit1.. ale w niektórych momentach do zmiennych globalnych z unit1 odwołuję się zamiast unit1.s_zmienna[1][0]:='cos';

to odwołuję sie w sposób następujący
s_zmienna[1][0]:='cos';

czy mój problem może wynikać z tego iz nie sprecyzowałem unitu1 przed zmienną ? bo s_zmienna należy do zmiennych globalnych unitu1..

Dziękuje za pomoc :)
EDIT:
ZAMIAST KLIKNĄĆ NA EDYTUJ, kliknąłem NA OPOWIEDZ, PRZEPRASZAM!

0

Napisałeś, że program może chodzić przez dłuższy czas i nic sie nie dzieje szczególnego, a czasem od razu sie wywala. Otóż w tym przypadku jest to całkowicie normalne.

Po pierwsze: dostęp do kontrolek z innego wątku, niż ten w którym te się znajdują jest dozwolony! - jest to normalna operacja na klasie. Dlatego program może działać - wątki co jakiś czas zmieniają właściwości kontrolek - raz ten raz ten - i nie dzieje się nic szczególnego.

Problem pojawi się gdy dwa wątki będą chciały zmienić właściwość jednocześnie! - a dokładniej mówiąc - gdy jeden wątek uruchomi procedurę set we właściwości, a wewnętrzny mechanizm kontrolki, który zmienia to (nr. rysuje coś) dostanie jeszcze raz odpalenie procedury przez drugi wątek - wszystko idzie w cholerę. Problemem nie są tu o tyle wątki, co mechanizm kontrolek w Delphi VCL.

Dlatego właśnie Twój program może działać bardzo długo, ale w końcu się wykrzaczy.

Synchronize() powinno załatwić sprawę - polega to na tym, że wpycha metodę którą podałeś w parametrze w wątek główny aplikacji.

Możesz też poczytać o sekcjach krytycznych oraz mutexach (można wykorzystać i napisać inne rozwiązanie).

0

Czyli twierdzisz ze odwołanie sie do zmiennej typu TStringList w jednym czasie przez kilka wątków może do tego doprowadzić ? hm.. program nie wywal sie <ort>Od razu </ort>a dział cały czas, ale najkrótszy czas po jakim sie wywalił to 3 godziny..

hm...
w OnConnect servera wprawdzie nie mam żadnej pętli tylko zwykły warunek ale dodałem appliaction.processmessaages; wiec nie koniecznie może być tez wina wątku, aczkolwiek usunę processmessages, i dodam ta w wątku te unit1.zmienaTStringLIst[0][4]... zobaczę czy to mi cos da, aha prędzej może to tyczyć sie socket.sendbuf w wątku niz tej zmiennej.

Dlatego szukam jakiegoś kierunku rozwiązania póki co wstrzymuje sie z tym do czasu waszych wypowiedzi, może one mi coś rozświetlą.

0
nikus napisał(a)

błąd pojawia się dość rzadko wręcz sporadycznie dlatego proszeo pomoc ludzi a nie narzedzie jakim jest Delphi

Synchronizacja do d... . Pewnie w ktoryms miejscu dobierasz sie do danych z wielu watkow a twoje typy danych nie sa przygotowane na takie cos.

0

prawda jest taka ze unitX to wątek, w unicieX wątka mam zmienna globalną typu string, co 10ms ta zmienna globalna ma zmienianą zawartość, ale wątpie aby to było tego przyczyną.

wracając do poprzedniego posta, pozmieniałem te nieadresowane zmienne w unicieX stawiąc przed zmienną unit1.zmienna bo nie we wszystkich zmiennych w tym wątku tak miałem póki co program nie wywalił sie od paru dni mimo obciążenia na maxa i częstych <ort>wachań </ort>łącza.

zobaczymy co bedzie działo się dalej... może pomyśle o mutex'ach (ale to nie najlepsze rozwiazanie)

0
nikus napisał(a)

wracając do poprzedniego posta, pozmieniałem te nieadresowane zmienne w unicieX stawiąc przed zmienną unit1.zmienna

To akurat jest bez znaczenia.

Sprawa jest banalna, postaram sie wytlumaczyc w sposob przystepny. Jesli w tym samym czasie dwa watki beda zapisywaly te sama zmienna albo jeden bedzie ja zapisywal a drugi odczytywal to pojawi sie blad. Tego nie mozna w ten sposob robic, tu nie ma zadnego usprawiedliwienia ani zadnego ale! Blad pojawia sia tak rzadko, poniewaz zapisanie zmiennej trwa mikroskopijna czesc sekundy, wiec w wiekszosci wypadkow odbywa sie bezkolizyjnie. Ale jak widac do czasu.

Rozwiazanie:
Dodajesz do uses SyncObjs, deklarujesz zmienna globalna blokada : TCriticalSection, w initialize tworzysz ja blokada := TCriticalSection.Create, w watku przed dostepem do zmiennej globalnej dajesz blokada.Enter a po zakonczeniu korzystania z niej blokada.Leave. To samo dotyczy kazdej zmiennej uzywanej wspolnie przez kilka watkow, dla kazdej zadeklaruj osobna blokade.

0

HoldenCaulfield jesteś wspaniały :) dużo mi to rozświetliło obrazu <ort>zaczołem </ort>przeglądać pomoc dotyczącą TCriticalSection, ale nadal nie wiem jednej rzeczy, czy TCriticalSection tworzy sie jako oddzielny proces stopujacy inne procedury czy tylko procedury z jednego wątku? mam 4 watki zawarte w unitcie 3,4 i 5, kazdy z watków wykonywany jest co 10 ms, każdy z wątków ma inne zmienne, ale watki zapisuja w jednej zmiennej TStringLIst w rożnych indexach okolo 70 razy na sekundę jakies dane nadpisując i odczytując, wiec jak dam w jednym wątku TCriticalSection to zatrzymam pozstale3 wątki na czas wykonania? może lepiej stworzyć 4 razy TCriticalSection oddzilenie dla każdego z wątku??

W związku z tym ze ciężko o tym poczytać na necie przygotowałem krótkiego arta jak użyć TCriticalSection... ale nie <ort>dokonca </ort>bo potrzebuje pomocy:P

Var
tcs:TCriticalSection; // deklarujemy w unicie głównym ?? czy unice watku ?

główna?.Create
tcs:=TCriticalSection.create;

wykorzystanie w wątku
tcs.enter;
zmienna[0][3]:='dsdf';
tcs.leave;

ktoś pomoże ?
dziękuje w WSPÓŁPRACY SIŁA!! :) :)

0
nikus napisał(a)

jak dam w jednym wątku TCriticalSection to zatrzymam pozstale3 wątki na czas wykonania? może lepiej stworzyć 4 razy TCriticalSection oddzilenie dla każdego z wątku??

Wlasnie o to chodzi, zeby wstrzymac pozostale watki przed zapisem w tej zmiennej, dopoki nie skonczy tego robic inny watek. To dziala jak szlaban przepuszczajacy po jednym samochodzie:

Watek pierwszy napotyka blokada.Enter - dostaje dostep, zaczyna bawic sie zmienna.
Watek drugi napotyka blokada.Enter - wstrzymuje swoje dzialanie czekajac na zwolnienie szlabanu.
Watek pierwszy zwalnia szlaban blokada.Leave.
Watek drugi dostaje dostep do zmiennej blokujac szlaban dla innych watkow.
itd.

Taki sam mechanizm musisz zastosowac dla kazdej zmiennej wykorzystywanej wspolnie przez watki, w tym takze dla tego komponentu serwerowego. Zeby bylo ladniej to te blokady warto wbudowac we wlasne klasy, ale na razie sie tym nie przejmuj.

nikus napisał(a)

tcs:TCriticalSection; // deklarujemy w unicie głównym ?? czy unice watku ?

Tak zeby wszystkie watki mialy do niej dostep (dla wszystkich watkow to musi byc ta sama zmienna).

0

heh jesteś wielki rozświetlasz mi coraz wiecej drogi :)

a ja wpadłem na inny pomysł co jest grane, co 10ms jest wykonywany wątek x 4(bo są 4 wątki)

testowałem TCriticalSection i działa wyśmienicie...:) ale znalazłem przyczynę, wątek wykonywany co 10 ms i nie zawsze nadążał się kończyć w tych 10ms co oznaczało ze tworzył się natłok wątków co prowadziło do przepełnienia pamięci "brak pamięci w magazynie" i Stack <ort>overlof </ort>jak dobrze napisałem :) program <ort>odrau </ort>sie <ort>wyłanczał </ort>:P

rozwiązałem chyba problem, dodałem koleją zmienną globalną max_watkow i dlaem warunek

if max_watkow < 300 then
Twate.create(false);

a w samym wątku dałem
inc(unit1.max_watek); // przy rozpoczęciu pracy watku+1
-->procedura execute<--
dec(unit1.max_watek); // po zakończeniu zwalnia limit-1

czyli maksymalna ilosc uruchomionych watkow to 299 :) wiecej sie nie uruchomi czeka do zwolnienia miejsca i dopiero sie wykonuje,

zrobiłem testowy program i patrzyłem jak sie wywala i jak działa dokladnie TCriticalSection, ale tak naprawdę wyszło na jawa przepełnienie magazynu.. wiec musialem zatamować rozmnażanie zbyt dużej ilości wątków :P

i działa prawidłowo!!! :)

co ty na to teraz :) ??

0
nikus napisał(a)

a ja wpadłem na inny pomysł co jest grane

Przede wszystkim przechwytuj bledy w Execute:

try
....
except
  on E:Exception do begin
    plik:=tfilestream.create(GetUniqueFileName('katalog', 'log-','txt'), fmCreate);
    plik.Write(E.Message);
    plik.Free;
  end;
end;

rozwiązałem chyba problem, dodałem koleją zmienną globalną max_watkow i dlaem warunek

a w samym wątku dałem
inc(unit1.max_watek); // przy rozpoczęciu pracy watku+1
dec(unit1.max_watek); // po zakończeniu zwalnia limit-1

Jezeli to jest w Execute to tez musi byc objete blokadami, najlepiej zastosuj InterlockedIncrement i InterlockedDecrement. Mozesz tez dodawac przed w Create, a odejmowac w OnTerminate, wtedy nie potrzeba blokady.

i działa prawidłowo!!!

Do czasu, jesli nie bedziesz uzywal blokad do wszystkich zmiennych modyfikowanych przez kilka watkow, to wczesniej czy pozniej sie wykrzaczy.

wiec musialem zatamować rozmnażanie zbyt dużej ilości wątków

Napisz moze do czego ten program sluzy, bo mam dziwne wrazenie, ze probujesz tworzyc na okolo cos bardzo prostego :)

0

to masz złe wrazanie ;)

prostym w tym wypadku jest tylko rozwiązanie.. :P hehe ;) EDIT: by się mogło zdawac ale nie jest to takie proste

co do wykrzaczania testowałem to w przyapdku <ort>komponętów </ort>wizualnych typu edit wykracza sie juz po 10-20 sekundach.

w przypadku zmiennych globalnych typu TSTringLIst, string, integer; moze chodzic całą noc z nadpisywaniem przez kilka wątków:)

wczoraj to wytestowałem, prosty testowy program do wykonywania "kolizji" tj. zapisu i odczytu zmiennej globalnej w jednym czasie, 0 wywrotek 0 błędów. Przeprowadziłem test na <ort>komponętach </ort>wizualnych program zawsze sie sypał juz po kilkunastu sekundach, oraz zmiennych globalnych TSTringLIst, integer, string chodziło az do tej pory jak wstałem :)

Z moich testów wynika ze problemem ni jest zapis w jednej zmiennej globalnej, lecz brak miejsca w magazynie gdy za długo stoi proces;/ no nic jeszcze potestuje...;/

Pozdrawiam

// SŁOWNIK!!! - Ł

0
nikus napisał(a)

prawda jest taka ze unitX to wątek, w unicieX wątka mam zmienna globalną typu string, co 10ms ta zmienna globalna ma zmienianą zawartość, ale wątpie aby to było tego przyczyną.

O Jezus Maria!

Holde Caulfield napisał(a)
nikus napisał(a)

tcs:TCriticalSection; // deklarujemy w unicie głównym ?? czy unice watku ?

Tak zeby wszystkie watki mialy do niej dostep (dla wszystkich watkow to musi byc ta sama zmienna).

Nie musi, jesli mamy watek wbudowany w obiekt to kazdy taki obiekt moze (a nawet powinien) miec swoj critical section, najprosciej zdziecziczyc obiekt z critical section i juz. Wydajniejszym rozwiazaniem jest uzycie TMultiReadExclusiveWriteSynchronizera, jednak implemantacja Borlanda nie jest najlepsza.

0
Z moich testów wynika ze problemem ni jest zapis w jednej zmiennej globalnej, lecz brak miejsca w magazynie gdy za długo stoi proces;/ no nic jeszcze potestuje...;/

i co zrobimy w takim wypadku ?

hm.. i mam kolejny problem jak użyć InterlockedIncrement i InterlockedDecrement?
Edit:
ja jeszcze testuje pare rozwiązań

0

Bez urazy ale wydaje mi sie ze nie wiesz co robisz i probujesz poprawic program metoda prob i bledow.

0
EgonOlsen napisał(a)

Bez urazy ale wydaje mi sie ze nie wiesz co robisz i probujesz poprawic program metoda prob i bledow.

wcale sie nie obrażam, w pewnym sensie tak jest, widzę rozwiązanie ale póki co nie umie go sprawnie wprowadzić w życie.. dlatego szukam pomocy i szanuje to ze ktoś sie tym w ogóle interesuje. DZIEKI SERDECZNE :)) kiedyś sie napijemy hehe ;:P

0

by się mogło zdawac ale nie jest to takie proste

Skad mozesz wiedziec, jesli nie chcesz nam tego powiedziec? Bez urazy, ale chyba sam przyznasz ze o programowaniu pojecie masz dosc mgliste? ATSD ten program jest tak bardzo tajny, ze nie mozesz napisac do czego sluzy?

zapisu i odczytu zmiennej globalnej w jednym czasie, 0 wywrotek 0 błędów

Czy to, ze akurat nie trafiles na błąd bo wystepuje bardzo rzadko jest powodem zeby swiadomie zostawiac taka luke w programie? Twoja decyzja...

EgonOlsen napisał(a)

Nie musi, jesli mamy watek wbudowany w obiekt to kazdy taki obiekt moze (a nawet powinien) miec swoj critical section, najprosciej zdziecziczyc obiekt z critical section i juz.

Jesli do tej samej zmiennej globalnej bedzie mialo dostep kilka watkow, to kazdy z tych watkow musi korzystac z tego samego TCriticalSection, inaczej to mija sie z celem.

0

Bez urazy, ale chyba sam przyznasz ze o programowaniu pojecie masz dosc mgliste?

Twierdzisz tak bo nie mam pojecia o TCriticalSection ? nie zgadzam sie z Tobą, może dlatego ze nie zrozumiles czego szukam.

Czy to, ze akurat nie trafiles na błąd bo wystepuje bardzo rzadko jest powodem zeby swiadomie zostawiac taka luke w programie? Twoja decyzja...

w kazdym watku była petla wykonywana 70 000 razy na zmiennej zapis watek byl uruchamiany co 10ms, operacje na tej zmiennej na pewno kolidowały, w wątkach i nie ma co tu dyskutować.

z TCriticalSection rezygnuje, mutexy tez odpadają... to zbyt powolne roziwaznie

PROBLEM rozwiązałem inaczej bardziej efektywniej niz wcześniejsze metody czekam na zwolnienie wątku i odejmuje zmienna max_watek, max watek dodaje przed wykonaniem wątku, potrzebna tez jeszcze jedna zmiena na zawieszone wątki potem sie sumuje watki + zawieszone/nie ukonczone tak wiec w jednej chwili nie ma mozliwosci żeby wykonywały się nowe wątki...

Jeszcze raz dziękuje za próbę pomocy:)

0
nikus napisał(a)

Twierdzisz tak bo nie mam pojecia o TCriticalSection?

Nie, twierdze tak np. na podstawie prob naprawy programu przez dodanie "unit1." przed zmiennymi, mylenie debuggera z kompilatorem itp.

nie zgadzam sie z Tobą, może dlatego ze nie zrozumiles czego szukam.

Nikt nie zrozumial, bo nie powiedziales co wlasciwie robi ten program.

w kazdym watku była petla wykonywana 70 000 razy na zmiennej zapis watek byl uruchamiany co 10ms, operacje na tej zmiennej na pewno kolidowały, w wątkach i nie ma co tu dyskutować.

Wczesniej twierdziles, ze blad moze pojawic sie po paru dniach. Wszystko przed nami. Zreszta odpalisz program na innym komputerze i blad moze pojawic sie po sekundzie. Ale tego nauczy Cie doswiadczenie, rzeczywiscie nie ma sensu dyskutowac.

0

nie czytałeś dokładnie moich postów, ja nic nie testowałem na głównej aplikacji, zrobiłem aplikacje testową która za zadanie miała doprowadzanie do kolizji zapis/odczyt w wątkach.

W apliacji głównej dopiero dzis rano, po testach wprowadziłem zmiany...

tak co do deburgera masz racje pomylo sie mi z kompilatorem, a dodawanie przed zmienna unit1 w wątku pomogło w spob taki ze zmiena byla sprecyzowana, ale to praktycznie nie m zznaczenia, wolalem to zdekalrowac juz dla samego siebie zeby miec spokój

1 użytkowników online, w tym zalogowanych: 0, gości: 1