Operacje I/O w Tcl - szczegóły.
Kanał - to tcl-owy
odpowiednik deskryptora w systemie operacyjnym;
kanały mogą dotyczyć plików lub gniazdek (czyli końcówek połączenia
tcp);
Operacje I/O:
- open/ close - otwieranie/ zamykanie pliku
open plik tryb; # zwraca kanał
- puts - zapis
puts [-nonewline] kanal dane
- gets/ read - odczyt linii tekstu/ odczyt ogólny
gets kanal zmienna; # czyta linie
tekstu
gets kanal
read kanał; # czyta wszystkie znaki, aż do końca pliku!
read kanał liczba_znaków
- fconfigure - konfigurowanie kanału
fconfigure kanal -opcja wartość
Tryb blokujący/ nieblokujący kanału.
tryb nieblokujący włączamy konfigurując odp kanał:
fconfigure $s -blocking 0
tryb nieblokujący dla puts:
działa inaczej niż w j. C
gdzie jeśli nie można pisać to jest zwracany bład;
tutaj puts nieblokujące
nigdy nie blokuje, ale dane są automatycznie
buforowane
przez tcl i wysyłane gdy to się stanie możliwe ...
Kolejka zdarzeń.
skrypt tcl uruchamiany przez "wish" ma pojedynczą pętle zdarzeń
która pobiera zdarzenia z
kolejki zdarzeń i je obsługuje
zdarzanie różnego typu są w tej samej kolejce !!!
(oprócz
fileevents są też zdarenia GUI, wątkowe, timery i inne)
komendy blokujące (np blokujące
gets) wyłączają chwilowo
pętle zdarzeń !!!
skrypty uruchamiane przez "tclsh" muszą same
utworzyć pętle zdarzeń
przy pomocy komendy "vwait zmienna"
komenda ta czeka
na modyfikacje "zmienna", równocześnie obslugując
zdarzenia z kolejki zdarzeń ...
UWAGA: nie powinno się używać vwait w proc obslugi zdarzenia,
gdyż to prowadzi do niebezpiecznych błędów!!!!!!!!!!
UWAGA 2: często dochodzi do następującego błedu:
pewna komenda blokuje pętle
zdarzeń, gdy są aktywne mechanizmy
opierające
się na pętli zdarzń ... wtedy one przestają działać
Problem zakleszczenia "duże
pytanie/ duża odpowiedź".
problem ten wystepuje gdy wysyłamy do serwera duże
pytanie
a serwer zwraca duzą odpowiedż;
przy
nieumiejętnym programowaniu łatwo doprowadzić tu do zakleszczenia
UWAGA: użycie
trybu
nieblokującego puts wcale nie jest dobrym rozwiązaniem!!!
gdyż w takim kodzie
fconfigure $s -blocking 0
puts
$s "duze dane"
fconfigure $s -blocking 1
set
odp [read $s]; # spodziewamy sie dużej odpowiedzi
operacja read może
zablokować pętle zdarzeń,
na
której opiera się przesyłanie danych nieblokującego puts !!!
Jak to należy zaprogramować ???
odp:
puts
blokujące,
read
nieblokujące i asynchroniczne
(przy pomocy fileevent) !!!