Czy wymagane jest użycie synchronize, jeśli w wątku chce przypisać coś do zmiennej globalnej?

0

Chce napisać bibliotekę, która ma dwie funkcje:

  1. Na wątku wysyła przez HTTP request, i gdy dostanie odpowiedź przypisuje ją do zmiennej globalnej
  2. druga funkcja jedynie pobiera wartość tej zmiennej globalnej (w późniejszym momencie)

założenie jest takie żeby nie blokować aplikacji, a w dwóch fazach otrzymać odpowiedź z serwera.

Mam tylko jeden problem, Synchronize(funkcja) nie jest wykonywana:

procedure TIndyInAThread.Execute();
const
 D_URL='http://www.internet.pl/webservice.php';
var
 LResult:String;
begin
 LResult:=FHTTP.Post(D_URL,FParams);

 if TryStrToInt(LResult,FCurrentNo) then
  ZMIENNA_GLOBALNA:=FCurrentNo;
//  Synchronize(UpdateVariable);

end;
//------------------------------------------------------------------------------
procedure TIndyInAThread.UpdateVariable();
begin
 ZMIENNA_GLOBALNA:=FCurrentNo;
end;

gdy z wątku przypisze jest ok, natomiast przez Synchronize to nie działa. I nie wiem jaka jest przyczyna.

Czytałem, że jednak musze użyć Synchronize dla bezpieczeństwa.

0

Przypisywanie inta o zgodnej wielkości cd. architektury (x86 - 32 etc.) jest atomowe.

0

tym bardziej że pewne jest że ni wywołam dwóch funkcji na raz, a w odstępie kilku sekund. Ale chciałbym żeby to było po bożemu, i czemu Synchronize nie działa. Czy jest jakieś ograniczenie jeśli chodzi o użycie wątku wewnątrz DLLki?

0

Nie wiem, co to jest u Ciebie

TIndyInAThread

ale Reme Lebeau pisał, że w Indy owszem serwer obsługuje połączenia klienckie w wątkach, ale klient nie jest przystosowany do pracy w wątku. Jak pogrzebiesz w necie, to to znajdziesz. Ktoś już się pytał o to, co i Ty i dostał od niego odpowiedz, że kod klienta ma być w main thread. Sądzę, że pozostaje Ci odpalenie procesu (rundll32) z tej biblioteki zamiast wątku. Za to w bibliotece serwer, który w wątku będzie się komunikował z klientem - procesem.

0

grzebałem i nigdy nie słyszałem, że nie powinno sie używać Indy w wątku, nawet na stackoverflow dają np taki przykład:
http://stackoverflow.com/questions/11547928/how-to-use-thread-delphi

A co z tym Synchronize. Czemu w DLL nie działa, a w normalnej aplikacji tak?

0

Sadam2 cuś chyba :-) czytał:

Answer from EDN by Remy Lebeau:

The DLL has its own self-contained copy of the VCL and RTL that are separate from the main app's copy. For the most part, this kind of threaded usage inside of the DLL is generally OK, but mainthread-sensitive functionality, like `TThread.Synchronize()` and `TThread.Queue()`, will not work unless you manually update the `System.MainThreadID` variable with the `ThreadID` of your "main" thread, unless your thread calls `CheckSynchronize()` periodically (which is normally called automatically when `TThread` "wakes up" the "main" thread when a `Synchronize`/`Queue` operation is performed).
0

Czy wymagane jest użycie synchronize, jeśli w wątku chce przypisać coś do zmiennej globalnej?

Nie jest wymagane "synchronize" , są inne mechanizmy komunikacji pomiędzy wątkiem głównym a wątkami pobocznymi .
"synchronize" zadziała tylko wtedy gdy wątek główny aplikacji przetwarza komunikaty, a jeśli nie przetwarza, to wątek poboczny będzie czekał w nieskończoność na wykonanie "synchronize"
Do komunikacji pomiędzy wątkiem głównym aplikacji a wątkami pobocznymi lepiej jest użyć w pierwszym rzędzie mechanizmów w typu "criticalsection" a w drugim "mutex". Są jeszcze "semafory" ale nie korzystałem z nich . "criticalsection" sprawdza się świetnie w obrębie jednej wielowątkowej aplikacji , a "mutexy" sprawdzają się przy wielu aplikacjach wymagających wyłącznego dostęp do wspólnego zasobu

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