Jesli mam 1-en watek ktory wykonuje dane zadanie oraz 2-di wqatek ktory robi cos innego, to co zrobic jesli sie "zderza" ze soba, no bo moze byc taka mozliwosc.
Maja one zyc ze soba w ort!
Co dla Ciebie znaczy zderzą? Chodzi ci o zakleszczenie, czy o problem sekcji krytycznej??
noooo jedno z tych co piszesz...
czyli...
chodzi o zakleszczenie
synchronizuj te wątki - sekcje krytyczne, muteksy, eventy - cokolwiek.
Nie chce tworzyć nowego tematu więc zadam tutaj. Mam sekcje krytyczne. Uzywam ich do tego jak zmieniam wielkość dynamicznej tablicy (rekordowej) i coś do niej dodaje. Z tej procki korzysta i aplikacja i wątek. Tutaj właśnie przydaje sie sekcja krytyczna. Mam tylko pytanie, czy pomiędzy sekcją krytyczną mam umieszczać kod który nawet odczytuje coś z tej tablicy? Czy sekcje są potrzebne tylko gdy zmieniam wartość/wielkość tablicy?
Mam tylko pytanie, czy pomiędzy sekcją krytyczną mam umieszczać kod który nawet odczytuje coś z tej tablicy?
[...] Czy sekcje są potrzebne tylko gdy zmieniam wartość/wielkość tablicy?
No jeżeli sekcją krytyczną obejmiesz np. tylko procedury zmiany rozmiaru tablicy, a odczyt z niej nie, no to wtedy nie ma mowy o żadnej synchronizacji. Owszem, czasami są sytuacje kiedy nie trzeba synchronizować sekcjami np. odczytu (chodzi o to żeby wątek nie był blokowany), ale i tak to wymaga zastosowania jakiegoś innego mechanizmu.
Istnieje pojęcie operacji atomowej (czyli niepodzielnej). Takie operacje nigdy nie będą przerwane "w trakcie" przez przełączenie wątków, dlatego nie trzeba ich chronić sekcjami krytycznymi lub tp. O ile wiem należy tu odczyt z pamięci zmiennej typu integer. Co do odczytu z tablicy nie wiem, zależy czy jest wewnetrznie zrealizowany w jednym kroku (odczytaj z adrestablicy+indeks) czy też w kilku krokach (x:=adrestablicy+index, <font color="red">[tu możliwość wejścia innego wątku i namieszania w tablicy, indeksie itd]</span> odczytaj z x).
Mam problem z sekcjami krytycznymi. Otóż co minute wątek aktualizuje dane w dynamicznej tablicy (rekordowej). Moment kiedy korzysta z tablicy <ort>zamknęłem </ort>w:
EnterCriticalSection(CritSect);
//....
LeaveCriticalSection(CritSect);
Użytkownik ma możliwość usunięcia danego rekordu. Chce sie zabezpieczyć przed usunięciem w momencie gdy wątek akurat coś przy tablicy robi. Tak więc usuwanie też dałem pomiedzy:
EnterCriticalSection(CritSect);
//....
LeaveCriticalSection(CritSect);
Korzystam z tej samej sekcji więc powinno grać, ale tak nie jest. W momencie usuwania rekordu gdy wątek coś przy nim robi aplikacja zamarza. Pomyslałem że musze chwile odczekać aż wątek zwolni sekcje, ale aplikacja zamarza na wieczność.
Dodam że procedura kliknięcia jest w Unicie1 (button) a wątek w Unicie2. Sekcja to zmienna globalna unitu2
var
CritSect : TRTLCriticalSection;
Inicjalizacje sekcji dałem też w unicie2 na samym końcu:
initialization
InitializeCriticalSection(CritSect);
finalization
DeleteCriticalSection(CritSect);
Pomyslałem że musze chwile odczekać aż wątek zwolni sekcje, ale aplikacja zamarza na wieczność.
A na pewno zwalnia??? Tak się dzieje gdy któryś z wątków nie zwolni sekcji.
Tak, i wlasnie nie wiem co sie dzieje :\
EnterCriticalSection(CritSect);
//....
LeaveCriticalSection(CritSect);
Zbyt wiele tu nie widać...
Pewnie masz błąd w tym usuwaniu.
Błędu w usuwaniu nie ma bo jak wątek nie korzysta z tablicy to usuwa dobrze hm... Pierwszy raz korzystam z sekcji, czy na pewno dobrze zrobiłem inicjacje? Sugerowałem się tym artem: http://www.delphicorner.f9.co.uk/articles/op4.htm
--EDIT--
Wcześniej usuwanie miałem jako zwykła procka klasy TForm. Teraz zmieniłem usuwanie jako osobny wątek i te dwa wątki pracują tak jak powinno być. Chociaż nie do końca, myślałem że usunięcie nastąpi gdy poprzedni wątek opusci sekcje a tu po prostu sekcja odrzuca nadchodzące wątkki i musze ponownie klikac na usun. Tak powinno byc?
--EDIT2--
Sorry, jednak usuwa. Usuwanie kontentu dynamicznej tabeli mam powiązane z ListView (widać zawartość), jak uruchomie wątek z usuwaniem to lista znika na kilka sekund (nawet gdy inny wątek nie korzysta z tablicy), dopiero potem wszystko widać na nowo. Bez wątka trwa to ułamek sekundy. Kod to:
//USUN
procedure TUsun.Execute;
var
i: integer;
begin
FreeOnTerminate := True;
if (frmMain.Lista_Aukcji.ItemIndex>-1) then
begin
EnterCriticalSection(CritSect);
for i:=frmMain.Lista_Aukcji.ItemIndex to High(Baza)-1 do
begin
Baza[i].User := Baza[i+1].User;
Baza[i].Numer := Baza[i+1].Numer;
Baza[i].Miejsce := Baza[i+1].Miejsce;
Baza[i].Ilosc := Baza[i+1].Ilosc;
Baza[i].Ofert := Baza[i+1].Ofert;
Baza[i].Kwota := Baza[i+1].Kwota;
Baza[i].KupTera := Baza[i+1].KupTera;
Baza[i].Koniec := Baza[i+1].Koniec;
end;
SetLength(Baza, Length(Baza)-1);
LeaveCriticalSection(CritSect);
frmMain.Lista_Aukcji.DeleteSelected;
frmMain.StatusBar.Panels.Items[2].Text := 'Aukcji: ' + IntToStr(Length(Baza));
end;
end;