Documente Academic
Documente Profesional
Documente Cultură
Laboratorul 12
Proiect
Realizați două aplicații distincte, de tipul dialog base, care să conțină fiecare două elemente de tip
Edit Control și un buton. Textul scris în unul din cele două elemente de tip Edit Control (de fiecare dată
același element), la apăsarea butonului, va apare în elementul Edit Control al celei de a doua aplicații. Cea
de a doua aplicație va permite trimiterea textului scris în celălalt Edit Control la prima aplicație atunci
când butonul va fi apăsat. Textul ce este trimis va avea o lungime de maximum 20 de caractere.
Elementul de afișare al noului mesaj ce tocmai a fost transmis de către cealaltă aplicație va fi deservit
de un fir de execuție ce va funcționa independent de restul programului.
Comunicația între cele două aplicații se va face prin intermediul mecanismului “cozi de mesaje”.
Cozi de mesaje
„Cozi de mesaje” este un mecanism de sincronizare a unor fire de execuție care este utilizat atunci
când este necesară sincronizarea între cel puțin 2 thread‐uri și, în plus, trebuie să existe și un anumit
schimb de informație între firele de execuție. Acest mecanism de sincronizare este unul specific
nucleului sistemului de operare.
În cadrul sistemului de operare Windows Embedded Compact ne putem imagina o multitudine de
modalități prin care două fire de execuție pot comunica date între ele. De exemplu, această comunicare
de date se poate realiza prin utilizarea regiștrilor sistemului de operare, a fișierelor și a bazelor de date –
ca să menționăm trei din cele mai utilizate metode.
Dar, atunci când cantitatea de date ce este necesară a fi transmisă este redusă și în plus mai sunt
necesare și sincronizări între cele două fire de execuție se pot utiliza aceste cozi de mesaje. Cozile de
mesaje sunt optimizate pentru utilizarea minimului de resurse sistem în procesul sincronizării și în cel al
transferului de date.
Din punct de vedere software o coadă de mesaje este o listă ordonată în care diferitele mesaje pot fi
adăugate sau înlăturate din listă. Cozile de mesaje prin care se realizează sincronizarea în Windows
Embedded Compact sunt de tip FIFO (First In First Out) sau FCFS (First Come First Server) – în sensul că
adăugarea se face la sfârșitul cozii în timp ce elementele se citesc și se elimină din coadă de la începutul
ei.
1
O coadă de mesaje poate fi dedicată unui fir de execuție sau poate fi o resursă comună a mai multor
fire de execuție. În mod similar mutex‐urilor, semafoarelor și evenimentelor, cozile de mesaje ce au un
nume propriu pot fi utilizate și pentru sincronizarea firelor de execuție ce aparțin la procese diferite.
Cu ajutorul funcției CreateMsgQueue se creează o coadă de mesaje ce poate avea sau nu un nume
asociat și căreia îi este asignat un hadler (identificator unic) prin intermediul căruia se pot, fie, citi
mesajele din coadă, fie scrie mesaje în coadă – funcție de valoarea TRUE sau FALSE a membrului
bReadAccess a structurii de date MSGQUEUEOPTIONS (structură a cărei adresă este utilizată drept
argument în cadrul acestei funcții). Prin intermediul unui handler asociat unei astfel de cozi se poate
realiza doar citirea sau doar scrierea într‐o astfel de coadă și nu ambele operații prin intermediul
aceluiași handler. Dar, dacă dispunem de un handler asociat cu o coadă de mesaje putem, prin
intermediul funcției OpenMsgQueue, crea un alt handler asociat aceleiași cozi pentru a realiza o altă
operație de scriere/citirea din ea complementară celei anterioare. Pentru eliberarea resurselor asociate
cu o coadă de mesaje și pentru închiderea ei se folosește funcția CloseMsgQueue. În schimb, pentru
eliberarea resurselor ocupate de un handler asociat unei cozi de mesaje se va folosi funcția standard
CloseHandle.
Sincronizarea, în cazul utilizării cozilor de mesaje, se face prin intermediul uneia din funcțiile:
WaitForSingleObject sau WaitForMultipleObjects. Pentru scrierea și citirea unui anumit mesaj se
folosesc funcțiile WriteMsgQueue și ReadMsgQueue. În general se poate trimite doar o singură variabilă
de un anumit tip de dată (de exemplu int, dword, char etc.). În momentul în care necesitatea ne impune
să trimitem mai multe variabile, le putem grupa pe acestea sub forma unei singure structuri de date pe
care să o scriem și, ulterior, să o citim într‐o/dintr‐o coadă de mesaje.
Informații ajutătoare
1. Pentru a trimite un număr variabil de caractere dar nu mai mare de 20 creați un nou tip de dată
de forma următoare:
typedef struct
{
char text[20];
int lungime;
} TestMsg;
În câmpul text salvați mesajul care îl luați de pe interfața grafică a programului (verificați ca
acesta să nu aibă mai mult de 20 de caractere) iar în câmpul lungime numărul de caractere a
acestui mesaj.
3. Fiecărei cozi îi vor fi atașate 2 handlere (unul poziționat în cadrul unei aplicații iar celălalt
poziționat în cea de a doua aplicație), vezi figura de mai jos. Cu ajutorul unuia se vor scrie date
(astfel structura MSGQUEUEOPTIONS va avea membrul msgQueueOption.bReadAccess =
FALSE) iar cu ajutorul celui de al doilea se vor citi datele (msgQueueOption.bReadAccess = TRUE).
4. În figura de mai jos se dau valorile cu care trebuie inițializată structura MSGQUEUEOPTIONS
pentru o funcționare corectă a programului.
Coadă de mesaje:
Com_Apl1_to Apl2
Aplicație 1 Aplicație 2
msgQueueOption.dwSize msgQueueOption.dwSize
= sizeof(MSGQUEUEOPTIONS); = sizeof(MSGQUEUEOPTIONS);
msgQueueOption.dwFlags msgQueueOption.dwFlags
= MSGQUEUE_ALLOW_BROKEN; = MSGQUEUE_ALLOW_BROKEN;
msgQueueOption.dwMaxMessages msgQueueOption.dwMaxMessages
= 0; = 0;
msgQueueOption.cbMaxMessage msgQueueOption.cbMaxMessage
= sizeof(TestMsg); = sizeof(TestMsg);
msgQueueOption.bReadAccess msgQueueOption.bReadAccess
= FALSE; = FALSE;
Edit Box de unde se va trimite text Edit Box de unde se va trimite text
Edit Box unde se va recepționa text Edit Box unde se va recepționa text
msgQueueOption.dwSize
msgQueueOption.dwSize
= sizeof(MSGQUEUEOPTIONS);
= sizeof(MSGQUEUEOPTIONS);
msgQueueOption.dwFlags
msgQueueOption.dwFlags
= MSGQUEUE_NOPRECOMMIT;
= MSGQUEUE_NOPRECOMMIT;
msgQueueOption.dwMaxMessages
msgQueueOption.dwMaxMessages
= 0;
= 0;
msgQueueOption.cbMaxMessage
msgQueueOption.cbMaxMessage
= sizeof(TestMsg);
= sizeof(TestMsg);
msgQueueOption.bReadAccess
= TRUE; msgQueueOption.bReadAccess
= TRUE;
Coadă de mesaje:
Fir independent Com_Apl2_to Apl1 Fir independent
de execuție de execuție
SO Windows Embedded Compact ce rulează pe sistemul de
dezvoltare OMAP3530, eBox3310 sau BeagleBox
3
4