background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      1 

 
 

 
 

Przesyłanie komunikatów 

5.   Przesyłanie komunikatów 
 
Sk

ładowe systemu rozproszonego są rozłączne logicznie i 

fizycznie. Aby wspó

łdziałać musza się komunikować. 

 
Przes

łanie  komunikatu  pomiędzy  procesami  jest  przesłaniem  pewnej  liczby 

bajtów  pomi

ędzy  tymi  procesami  według  ustalonego  protokołu.  Przesłanie 

komunikatu jest operacj

ą atomową. 

 
 
Mo

żliwość 

przekazywania 

komunikatów 

pomi

ędzy 

procesami 

jest 

fundamentaln

ą własnością  systemu  QNX.  

 
W  systemie  QNX  wyró

żniamy  następujące  akcje  związane  z  przesyłaniem 

komunikatów pomi

ędzy procesami P1 i P2: 

 
1)  Wys

łanie komunikatu przez P1 do P2 

2)  Odbiór komunikatu przez P2 
3)  Przes

łanie odpowiedzi zwrotnej od P2 do P1. 

 

5.1 

 Wysłanie komunikatu 

Komunikat do procesu P wysy

ła się wykonując funkcję Send. Prototyp funcji 

Send podany zosta

ł ponizej. 

 
int Send(pid_t pid, void * smsg, void * rmsg, unsigned 
sbytes,unsigned rbytes) 
 
Znaczenie parametrów powy

ższej funkcji jest następujące: 

pid  

PID procesu docelowego P 

smsg 

adres bufora danych wysy

łanych 

rmsg 

adres bufora danych odbieranych 

sbytes  

liczba bajtów wysy

łanych 

rbytes  

max. liczba bajtów odbieranych 

 
Funkcja zwraca:  0 – sukces,  -1  - b

łąd  

 
Dzia

łanie funkcji Send jest następujące: 

1)  Komunikat 

smsg wysyłany jest do procesu docelowego po czym proces 

bie

żący ulega zablokowaniu. 

2)  Proces wysy

łający jest zablokowany do czasu gdy proces docelowy nie 

odbierze wys

łanego komunikatu i nie prześle odpowiedzi. 

3)  Po otrzymaniu odpowiedzi jest ona umieszczana w buforze rmsg i proces 

bie

żący jest wznawiany. 

 
 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      2 

 
 

 
 

Przesyłanie komunikatów 

Proces P1

Proces P2

Send(...)

Receive(...)

RECEIVE_BLOCKED

Reply(...)

REPLY_BLOCKED

Komunikat

Odpowied

ź

READY

READY

Blokada

Odblokowanie

Odblokowanie

Blokada

 

 

Wymiana komunikatów pomiędzy procesami P1 i P2. Funkcja Receive 
poprzedza funkcję Send

 
 

Proces P1

Proces P2

Send(...)

Receive(...)

Reply(...)

REPLY_BLOCKED

Komunikat

Odpowied

ź

READY

READY

Blokada

Odblokowanie

SEND_BLOCKED

 

Wymiana komunikatów pomiędzy procesami P1 i P2. Funkcja Send 
poprzedza funkcję Receive

 

5.2 

 Odbiór komunikatu 

Do odbioru komunikatów przez proces P s

łuży funkcja Receive. 

 
pid_t Receive(pid_t pid, void * msg, unsigned rbytes) 
 
Znaczenie parametrów powy

ższej funkcji Receive jest następujące: 

pid    

PID procesu nadaj

ącego lub 0 – gdy odbiór od wszystkich 

procesów 

rmsg   

adres bufora danych odbieranych 

rbytes  

max. liczba bajtów odbieranych 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      3 

 
 

 
 

Przesyłanie komunikatów 

 
Funkcja zwraca:  > 0 – PID procesu który nada

ł komunikat, - 1 - błąd 

 

 
Gdy zachodzi potrzeba odbioru komunikatu nale

ży wykonać funkcję Receive. 

Zwykle  jako  parametr  pid  wstawiamy  0  co  oznacza 

że  odbierane  będą 

komunikaty od wszystkich procesów. 
 
Dzia

łanie funkcji Receive zależy od tego czy  istnieją komunikaty które zostały 

wcze

śniej wysłane do procesu P przez inne procesy. Jeśli tak było to muszą 

one oczekiwa

ć w kolejce Q nieodebranych komunikatów.  

 
 
 
Dzia

łanie funkcji jest następujące: 

 

1.  Gdy w kolejce Q s

ą nieodebrane komunikaty pierwszy z nich usuwany jest 

z kolejki Q i umieszczany w buforze 

msg. Funkcja zwraca PID procesu 

który wys

łał ten komunikat. System powoduje odblokowanie procesu 

wysy

łającego komunikat. Proces bieżący nie ulega zablokowaniu. 

2.  Gdy kolejka Q jest pusta proces P ulega zablokowaniu do czasu nadej

ścia 

takiego komunikatu. Zablokowany proces jest w stanie 
RECEIVE_BLOCKED. 

 
 

Istnieje mo

żliwość zmiany uporządkowania tej kolejki na uporządkowanie 

wed

ług priorytetów procesów przysyłających komunikaty. Należy w tym 

przypadku u

żyć funkcji qnx_pflags(…).  

 
Priorytetowa organizacja  kolejki poci

ąga za sobą możliwość zagłodzenia 

procesów. 

P1

PN

P

K1

Kn

K2

Procesy wysylaj

ące

komunikaty

Proces odbieraj

ący

komunikaty

Kolejka Q

nieodebranych

komunikatow

P2

 

Proces P nie odebra

ł komunikatów wysłanych przez procesy P1, P2, …PN. 

Komunikaty oczekuj

ą w kolejce Q. 

 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      4 

 
 

 
 

Przesyłanie komunikatów 

 
 

5.3 

 Wysłanie odpowiedzi na komunikat 

 
 

pid_t Reply(pid_t pid, void * msg, unsigned sbytes) 

 

pid 

PID procesu nadaj

ącego lub 0 – odbiór od wszystkich 

msg 

adres bufora danych wysy

łanych 

sbytes  maksymalna liczba bajtów wysyłanych 

 

Funkcja zwraca: > 0 – PID procesu który nada

ł komunikat,   1 - błąd 

 

5.4 

 Warunkowy odbiór komunikatu 

 

pid_t Creceive(pid_t pid, void * msg, unsigned rbytes) 

 

Funkcja nie powoduje zablokowania procesu bie

żącego gdy brak 

komunikatów. 

 

pid  

> 0 - PID procesu nadaj

ącego  

   0 - odbiór od wszystkich procesów 

rmsg 

adres bufora danych odbieranych 

rbytes  

max. liczba bajtów odbieranych 

 
Funkcja zwraca: 
> 0 – PID procesu który nada

ł komunikat 

- 1 - b

łąd 

 

 
Na  poni

ższym  rysunku  za  pomocą  sieci  Petriego  przedstawiono  wymianę 

komunikatów pomi

ędzy procesami P1 i P1. 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      5 

 
 

 
 

Przesyłanie komunikatów 

Proces P1 wysylaj

ący

komunikat

Proces P2 odbieraj

ący

komunikat

Ready

Send

blocked

Reply

blocked

Ready

Receive

blocked

Ready

Receive

Reply

Send

 

Sie

ć Petriego przedstawiająca wymianę komunikatów pomiędzy procesami 

P1 i P2 

5.5 

 Nazwy 

Proces  P1  mo

że  wysłać  komunikat  do  P2  o  ile  zna  jego  PID.  Bez 

dodatkowych  mechanizmów  tylko  procesy  b

ędące  w  relacji  macierzysty  / 

potomny mog

ą się w ten sposób komunikować.  

 
Aby umo

żliwić komunikowanie się procesów niezwiązanych, w systemie QNX 

wprowadzono mechanizm nazw.  
 
Procesy  mog

ą  rejestrować  swoje  nazwy  w  systemie.  Nazwy  są  zwykłymi 

łańcuchami.  Inne  procesy  mogą  zwrócić  się  do  systemu  o    PID    procesu 
podaj

ąc    jego  nazwę.    Mechanizm  ten  działa  także  przez  sieć  i  nosi  nazwę 

lokalizacji. 
 

5.5.1   Rejestracja nazwy 
Proces rejestruje si

ę poprzez wykonanie funkcji: 

 
int qnx_name_attach(nid_t nid, char * name) 
 

nid 

Identyfikator w

ęzła na którym nazwa jest rejestrowana (0 – węzeł bieżący) 

name  Nazwa rejestrowanego procesu 
 
Gdy nazwa zaczyna si

ę od znaku  /  jest widoczna w całej sieci. Nazwa może 

by

ć też zarejestrowana  na określonym węźle. Funkcja zwraca: 

 > 0  - identyfikator nazwy (

ang. name ID) – liczba typu int używana w innych 

funkcjach. 
  -1   - gdy rejestracja si

ę nie udała. 

 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      6 

 
 

 
 

Przesyłanie komunikatów 

5.5.2   Lokalizacja nazwy 
PID procesu o znanej nazwie uzyskuje si

ę poprzez wywołanie funkcji: 

 

pid_t qnx_name_locate(nid_t nid, char * name, unsigned 
size, NULL) 
 

nid 

Identyfikator w

ęzła na którym nazwa jest rejestrowana (0 – węzeł bieżący) 

name  Nazwa lokalizowanego procesu 
size  Długość komunikatu który będzie przesyłany pomiędzy procesami 
 
Funkcja zwraca: 

 > 0  - identyfikator procesu  
  -1   - gdy lokalizacja si

ę nie udała. 

 
 

Gdy 

nid = 0 proces będzie lokalizowany najpierw na bieżącym węźle a 

potem w sieci. Gdy

  nid # 0 proces będzie lokalizowany tylko na  węźle o 

numerze nid. 
Gdy lokalizowany proces le

ży na innym węźle automatycznie tworzone jest 

po

łączenie wirtualne (ang. Virtual Circuit) pomiędzy węzłami.  

 
 
Je

żeli chcemy aby działała lokalizacja sieciowa, na przynajmniej jednym z 

w

ęzłów sieci musi być uruchomiony proces nameloc. Zaleca się aby liczba 

w

ęzłów z uruchomionymi procesami nameloc nie przekraczała 3. 

 

5.5.3   Wyrejestrowanie nazwy 
Nazwa kasowana jest si

ę poprzez wywołanie funkcji: 

 

int qnx_name_detach(nid_t nid, int name_id) 
 

nid 

Identyfikator w

ęzła na którym nazwa jest kasowana (0 – węzeł bieżący) 

name_id  Identyfikator  kasowanej nazwy – liczba zwracana przez funkcję 

qnx_name_attach 

 
Funkcja powoduje usuniecie nazwy o identyfikatorze 

name_id z bazy nazw. 

Funkcja zwraca: 

   0  - gdy wyrejestrowanie si

ę udało  

  -1  - gdy operacja si

ę nie udała. 

 
 

5.6 

 Przykład komunikacji 

Przyk

ład procesu klienta P1 i serwera P2 wymieniające komunikaty. Procesy 

mog

ą być uruchomione na tym samym lub oddzielnych węzłach połączonych 

sieci

ą. 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      7 

 
 

 
 

Przesyłanie komunikatów 

 

Klient

P1

Proces wysylaj

ący

komunikaty

Proces odbieraj

ący

komunikaty

Serwer

P2

 Komunikat

 Odpowiedź

 

 

Proces klienta i serwera wymieniaj

ą komunikaty 

 

// Proces klienta P1 – wysyła komunikaty 
#include <sys/kernel.h> 
#include <sys/name.h> 

typedef struct { 
                int  typ;        

                char text[80];  
        }       msg_type; 
 

 
main(void){ 
  int pid,i; 

  msg_type msg; 
  // Lokalizacja serwera ----------- 
  pid = qnx_name_locate(0,”serwer1”,sizeof(msg_type),     

NULL); 
  if(pid == -1) { perror("LOKALIZACJA"); exit(1);} 

  msg.typ = 0; 
  for(i=0;i<10;i++) { 
          sprintf(msg.text,"Komunikat - %d\n",i);    

          // Wysłanie komunikatu -------- 
          res = Send(pid,&msg,&msg,sizeof(msg), 
sizeof(msg));     

          printf("Wysłano: %s \n",msg.text); 
          sleep(1); 
   }; 

   exit(0); 

Proces klienta wysy

łający komunikaty 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      8 

 
 

 
 

Przesyłanie komunikatów 

 

// Proces serwera P2 – odbiera komunikaty i wysyła 
odpowiedzi 

#include <sys/kernel.h> 
#include <sys/name.h> 
typedef struct { 

                int  typ;        
                char text[80];  
        }       msg_type; 

 
 

main(void){ 
  int pid,my_name; 
  msg_type msg; 

  // Rejestracja nazwy ---------  
  my_name = qnx_name_attach(0,”/serwer1); 
  if(my_name == -1) { perror("ATTACH"); exit(1);} 

  do { // Pętla główna -------- 
      // Odbiór komunikatu ------------     
      pid = Receive(0,&msg,sizeof(msg));     

      printf("Komunikat od %d text: %s\n ",pid,msg.text); 
      msg.msg_type = 1; 
      // Wysłanie odpowiedzi ----------  

      Reply(pid,&msg,sizeof(msg)); 
  } while(1); 

  qnx_name_detach(0,my_name); 
 } 

Proces serwera odbieraj

ący komunikaty 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      9 

 
 

 
 

Przesyłanie komunikatów 

 

5.7 

 Przekazywanie komunikatów przez sieć – połączenia wirtualne 

System QNX jest od podstaw zbudowany jako rozproszony system sieciowy.  

punktu 

widzenia 

programisty 

komunikacja 

pomi

ędzy  procesami 

zlokalizowanymi na jednym w

ęźle nie różni się od komunikacji przez sieć.  

 
 

5.7.1   Budowa połączenia wirtualnego 

 

P1

P2

VC1

VC2

Bufor 1

Bufor 2

Net

Driver

NIC

MEDIUM

Net

Driver

NIC

WEZEŁ 1

WEZEŁ 2

Poziom aplikacji

Poziom systemu

Mikro-

jądro

Mikro-

jądro

 

Po

łączenie wirtualne pomiędzy procesami P1 i P2 

 
 

Po

łączenie wirtualne jest tworzone podczas lokalizacji procesu serwera. 

Tworzone s

ą procesy wirtualne VC1 i VC2 które są pośrednikami w transmisji 

komunikatów.  
Proces VC1 reprezentuje proces P2 na w

ęźle 1 a proces VC2 reprezentuje 

proces P1 na w

ęźle 2.  

 Ka

żdy z procesów  wirtualnych dysponuje buforem na komunikaty. 

 

Ka

żde połączenie wirtualne musi utrzymywać następujące informacje: 

1.  PID procesu lokalnego  i zdalnego. 
2.  VID procesu lokalnego i zdalnego 
3.  NID (numery w

ęzłów)  lokalnego i zdalnego 

 
  

 

Przyk

ład  - demonstracja testowania połączenia wirtualnego. 

Problem: z w

ęzła 3 próbujemy wylistować znaki przychodzące na port 

szeregowy w

ęzła 1 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      10 

 
 

 
 

Przesyłanie komunikatów 

 
Na w

ęźle 3 wykonujemy polecenie: 

$ cat //1/dev/ser1 
 
Na innej konsoli w

ęzła 3 piszemy: 

$ sin vcs 

 
 

LOCAL  

 

 

 

 

 

REMOTE 

VID  PID   LK  STATE  PROG         NID VID   PID PROG 

15275 15273 1   REPLY  //3/bin/cat 1 

26518 16 //1/bin/Dev32 

 

Na w

ęźle 1 wykonujemy polecenie: 

$ sin vcs 
Na konsoli pojawia si

ę informacja o połączeniach wirtualnych widzianych z 

w

ęzła 3. 

LOCAL  

 

 

 

 

REMOTE 

VID   PID LK STATE  PROG          NID VID   PID    PROG 

26518 16  1  REPLY  //1/bin/Dev32 3   15275 15273 //1/bin/cat 

 

Po

łączenie wirtualne posiada dwa końce i identyfikowane jest przez dwa 

parametry – NID i VID. 
 
 

cat

15273

Dev32

16

3 / 15275

1 / 26518

 

Po

łączenie wirtualne pomiędzy procesami cat na węźle 3 i Dev32 na węźle 1 

 

5.7.2   Kontrola połączenia wirtualnego 
System operacyjny samoczynnie kontroluje sprawno

ść połączenia 

wirtualnego. Po

łączenie wirtualne stanie się nieoperatywne gdy: 

 
1.  Zdalny komputer zostanie wy

łączony lub uszkodzony. 

2.  Po

łączenie sieciowe do zdalnego komputera ulegnie uszkodzeniu. 

3.  Zdalny proces si

ę zakończy. 

 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      11 

 
 

 
 

Przesyłanie komunikatów 

 

5.8 

 Depozyty – powiadomienia asynchroniczne 

W  aplikacjach  wspó

łbieżnych potrzebny jest często nieblokujący mechanizm 

powiadamiania procesów o pewnych zdarzeniach. 
 
 
W  systemie  QNX  taki  mechanizm  jest  zaimplementowany  i  nosi  tam  nazw

ę 

depozytu

 (ang. proxy).  

Depozyty mog

ą być przesyłane przez sieć.  

 
Depozyty  s

ą  rodzajem  komunikatów  o  ustalonej  treści  (zwykle  zerowej)  nie 

wymagaj

ącym potwierdzenia. 

 
Depozyty s

ą stosowane w następujących sytuacjach: 

1.  Proces  chce  powiadomi

ć  inny  proces  o  zdarzeniu,  ale  nie  może  sobie 

pozwoli

ć na zablokowanie się. 

2.  Proces  chce  powiadomi

ć  inny  proces  o  zdarzeniu,  ale  nie  potrzebuje 

informacji zwrotnej. 

3.  U

żywane są w procedurach obsługi przerwań (ang. interrupt handler). 

 
Tworzenie  depozytu: 
Depozyt tworzony jest za pomoc

ą funkcji: 

 
int qnx_proxy_attach(pid_t pid, char * data, int nbytes, 

int priority) 

 

pid 

PID procesu b

ędącego właścicielem depozytu (0 gdy jest to proces 

wykonuj

ący funkcję). 

data 

Zawarto

ść depozytu – zwykle 0. 

nbytes 

D

ługość informacji zawartej w depozycie – zwykle 0; 

priority  Priorytet depozytu (gdy –1 – będzie on taki jak priorytet procesu 

wykonuj

ącego funkcję). 

 

Funkcja zwraca: 
> 0 -  identyfikator depozytu 
 -1 -   b

łąd 

 
Wys

łanie depozytu: 

Depozyt wysy

łany jest za pomocą funkcji: 

 

pid_t Trigger(pid_t proxy) 
 

proxy   Identyfikator depozytu – wartość zwracana przez funkcję  

qnx_proxy_attach

  
Wykonanie funkcji Trigger powoduje wys

łanie depozytu proxy do procesu 

który jest jego w

łaścicielem. 

 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      12 

 
 

 
 

Przesyłanie komunikatów 

Funkcja zwraca: 
> 0 -  identyfikator procesu który jest w

łaścicielem depozytu 

 -1 -   b

łąd 

 

Odbiór depozytu: 
Odbiór depozytu nast

ępuje poprzez wykonanie funkcji Receive. Jeżeli 

proces jest zablokowany na funkcji  

Receive i do procesu tego zostanie 

dostarczony depozyt, proces ulega odblokowaniu i funkcja  

Receive zwraca 

identyfikator depozytu. 
 
Kasowanie depozytu 
Depozyt jest kasowany za pomoc

ą funkcji: 

 
int qnx_proxy_detach(pid_t proxy)  
 
proxy   Identyfikator kasowanego depozytu – wartość zwracana przez funkcję 

qnx_proxy_attach

 
Funkcja zwraca: 0 – sukces, -1 b

łąd 

 
W

łasności depozytów: 

1.  Wys

łane depozyty nie wymagają potwierdzenia. 

2.  Nieodebrane depozyty s

ą kolejkowane (w ilości do 65535). Zostaną 

odebrane przy kolejnym wywo

łaniu funkcji Receive

3.  Ka

żdy depozyt należy do procesu który go utworzył.  

4.  Depozyt mo

że być wysłany z dowolnego procesu, ale zawsze trafia do 

procesu który jest jego w

łaścicielem. 

 

 
 

Proces P1

Proces P2

proxy = qnx_proxy_attach(0,0,0,-1)

pid = receive(0,msg,size)

RECEIVE_BLOCKED

Trigger(proxy)

Odblokowanie

U

życie depozytu do odblokowania procesu

 

 

 

 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      13 

 
 

 
 

Przesyłanie komunikatów 

 

 
 
 

 
 #include <sys/kernel.h> 
 main() { 

  int i,sec = 0; 
  pid_t proxy; 
  proxy = qnx_proxy_attach(0,0,0,-1); 

  if(proxy == -1) { perror("Proxy"); exit(0);} 
  if(fork() == 0) { //Proces wysylajacy proxy ----  
       for(i=0;i<20;i++) { 

          Trigger(proxy); // Wyslanie proxy 
          sleep(1); 
     }; 

     exit(0); 
  } 
  // Proces odbierajacy  -------------------------  

  do { 
      pid = Receive(0,&msg,sizeof(msg));  

      // Odbior proxy lub komunikatu   
      if(pid == proxy) { // Proxy 
         printf("Sekund %d\n",sec++); 

         if(sec > 10) break;          
      } else { // Komunikat 
 

      printf("Komunikat \n"); 

 

 

  .... 

      } 
  } while(1); 

  qnx_proxy_dettach(0,0,0,-1); 
}   

Przyk

ład zastosowania depozytu                                   

 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      14 

 
 

 
 

Przesyłanie komunikatów 

Przykład - prosty serwer sekwencyjny w systemie QNX 

Serwer sekwencyjny to serwer sk

ładający się z jednego tylko 

procesu. W danej chwili mo

że on obsługiwać tylko jednego klienta.  

 
Kroki klienta: 
1.  Lokalizacja serwera 
2.  Utworzenie komunikatu specyfikuj

ącego żądanie 

3.  Wys

łanie komunikatu do procesu serwera 

4.  Odbiór odpowiedzi. 
5.  Wykorzystanie wyniku. 
 
Kroki serwera: 
1.  Rejestracja nazwy w

łasnej w serwerze nazw. 

2.  Odbiór zlecenia. 
3.  Identyfikacja zlecenia  
4.  Realizacja zlecenia. 
5.  Wys

łanie odpowiedzi do klienta 

 
Zlecenia do serwera  musza by

ć kolejkowane. Podstawowe 

schematy obs

ługi klientów: 

-  Send driven 
-  Reply driven 
 

Klienci

Serwer

P1

K1

KN

P2

P3

P4

Procesy oczekujace w

stanie REPLY_BLOCKED

P5

P6

P7

Procesy oczekujace w

stanie SEND_BLOCKED

Metody kolejkowania nie obs

łużonych klientów. 

 
 
Kroki implementacji systemu klient – serwer : 
1.  Zaplanowanie formatu komunikatów. 
2.  Implementacja procesu klienta. 
3.  Implementacja procesu serwera. 
 
Planowanie formatu komunikatów 
1.  Dla ka

żdego zlecenia należy przygotować odpowiednią 

struktur

ę danych a zleceniom przypisać unikalne numery.  

2.  Struktury nale

ży zgrupować w unię.  

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      15 

 
 

 
 

Przesyłanie komunikatów 

 

#define SERWER_NAME „/mój_serwer” 
#define MSG1  1 

// Identyfikator zlecenia 1 

typedef struct { 

// Struktura zlecenia 1  

 

int typ_zlec;  // Typ zlecenia 

 

int par1;    

// Parametr 1 

 

…… 

 } st1_t; 
 
#define MSG1  2 

// Identyfikator zlecenia 2 

typedef struct { 

// Struktura zlecenia 2  

 

int typ_zlec;  // Typ zlecenia 

 

char *nazwa;    

// Parametr 1 

 

…… 

 } st2_t; 
 
typedef union { 

// Struktura komunikatu (unia) 

 

int typ_zlec;  // Typ zlecenia 

 

st1_t st1;     // Typ zlecenia 1 

 

st2_t st2;     // Typ zlecenia 2 

 

…… 

 } msgu_t; 

Definicje wspólnych struktur danych procesów klienta i serwera  

 
 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      16 

 
 

 
 

Przesyłanie komunikatów 

// Proces klienta – wysyła komunikaty 
#include „common.h” 
main(void){ 
  int pid; 
  st1_t msg; 
  // Lokalizacja serwera ----------- 
  pid = qnx_name_locate(0,SERWER_NAME, 
        sizeof(msg),NULL); 
  msg.typ_zlec = MSG1; 
  do { 
       // Przygotowanie pol komunikatu 
       msg.par1 = …. 

 

       // Wysłanie komunikatu -------- 
      res =Send(pid,&msg,&msg,sizeof(msg), 
           sizeof(msg));     
       if(res < 0) { // Obsluga błędu } 
       // Wykorzystanie odpowiedzi --- 
       x = msg.par2; 
       …  
   } 

Szkic procesu klienta 

 

PDF created with pdfFactory trial version 

www.pdffactory.com

background image

J

ędrzej Ułasiewicz        Programownie aplikacji współbieżnych                                 str.      17 

 
 

 
 

Przesyłanie komunikatów 

 
// Proces serwera – wysyła komunikaty 
#include „common.h” 
main(void){ 
  int pid; 
  msgu_t msg; 
  st1_t  msg1; 
  st1_2  msg2; 
  // Rejestracja serwera ----------- 
  pid = qnx_name_attach(0,SERWER_NAME); 
  do {    // Odbiór komunikatu ---------- 
          pid = Receive(0,&msg,sizeof(msg));     
          if(pid < 0) { // Obsluga błędu } 
          // obsluga zleceń --- 
          switch(msg.typ_zlec) { 
            case MSG1: // Obsługa zlecenia typu 1 
--- 
                     … 
                     
Reply(pid,&msg1,sizeof(msg1); 
                     break; 
            case MSG2: // Obsługa zlecenia typu 2 
--- 
                     … 
                     
Reply(pid,&msg2,sizeof(msg2); 
                     break; 
          } 
          …  
   } while(aktywny); 

Szkic procesu serwera 

 

PDF created with pdfFactory trial version 

www.pdffactory.com