Forum SUM na Politechnice Poznańskiej, SKiSR Strona Główna SUM na Politechnice Poznańskiej, SKiSR
http://www.zaoczniak.glt.pl
 
 FAQFAQ   SzukajSzukaj   UżytkownicyUżytkownicy   GrupyGrupy   GalerieGalerie   RejestracjaRejestracja 
 ProfilProfil   Zaloguj się, by sprawdzić wiadomościZaloguj się, by sprawdzić wiadomości   ZalogujZaloguj 

ćwieczenia
Idź do strony 1, 2  Następny
 
Napisz nowy temat   Odpowiedz do tematu    Forum SUM na Politechnice Poznańskiej, SKiSR Strona Główna -> SW
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Mercucio
Młodszy forumowicz



Dołączył: 04 Gru 2006
Posty: 10
Przeczytał: 0 tematów

Ostrzeżeń: 0/5

PostWysłany: Pon 9:34, 04 Gru 2006    Temat postu: ćwieczenia

Witam! Na prośbe kilku osób wrzucam to co wypociliśmy na ćwiczeniach.
Ostrzegam mimo iż program dziala i robi to co miał robić, dr Szychowiak ocenił go zaledwie na 4 ( będę musiał jakoś z tym żyć Smile ).
Plik slave.c ma 150 lini a podobno można zrobić to na jednym ekranie, więc nie jest to optymalny kod.

no to zaczynamy:

Kod:
 
#include <stdio.h>
#include <stdlib.h>
#include <pvm3.h>
 
#define SLAVENAME "slave"
#define SLAVENUM   3
 
#define NAMESIZE   64
 
#define MSG_MSTR 1
#define MSG_SLV  2
 
#define timeout 3


master.c
Kod:

#include "def.h"
#include <stdio.h>
 
main()
{
   int mytid;
   int tids[SLAVENUM];      /* slave task ids */
   char slave_name[NAMESIZE];
   char napis[50];
   int nproc, i, who, last;
 
   mytid = pvm_mytid();
 
   nproc=pvm_spawn(SLAVENAME, NULL, PvmTaskDefault, "", SLAVENUM, tids);
 
 
   for( i=0 ; i<nproc ; i++ )
   {
      pvm_initsend(PvmDataDefault);
      pvm_pkint(&mytid, 1, 1);
      pvm_pkint(&i, 1, 1);
      pvm_pkint(&tids[(i+nproc+1)%nproc],1,1);
      pvm_pkint(&tids[(i+nproc-1)%nproc],1,1);
      pvm_send(tids[i], MSG_MSTR);
   }
 
   for( i=0;i<nproc;i++)
   {
       pvm_recv(-1,MSG_SLV);
       pvm_upkstr(napis);
       printf("%s\n",napis);
   }
 
   while(1)
   {
       pvm_recv(-1,MSG_SLV);
       pvm_upkstr(napis);
       printf("%s\n",napis);
   }
 
   pvm_exit();
}


slave.c
Kod:

#include "def.h"
#include <sys/time.h>
 
#define true 1
#define false 0
 
void wyslij(int tok,int nexttid,int master_tid,int mytid)
{
    int temp;
    char string[50];
    srand(time(0));
    temp=rand()%5;
    if(temp!=3)
    {
       pvm_initsend(PvmDataDefault);
           pvm_pkint(&tok,1,1);
       pvm_send(nexttid,MSG_SLV);     
    }
    else
    {
       pvm_initsend(PvmDataDefault);
       sprintf(string,"Jestem %d , NIE WYSYLAM TOKENA",mytid);
           pvm_pkstr(string);
       pvm_send(master_tid,MSG_SLV);
    }
}
 
void sekcja_krytyczna(int master_tid,int mytid,int prevtid,int token,int time3)
{
       int time1,time2,buf,temp,time4;
       struct timeval time_trecv;         
       char string[50];
       time_trecv.tv_sec=time3;
       time_trecv.tv_usec=0;
 
       pvm_initsend(PvmDataDefault);
       sprintf(string,"Jestem %d , token to %d i wchodze do SK",mytid,token);
           pvm_pkstr(string);
       pvm_send(master_tid,MSG_SLV);
 
 
    while(time3>0)
    {
       time(&time1);
       if(buf=pvm_trecv(prevtid,MSG_SLV,&time_trecv))
       {
      pvm_upkint(&temp,1,1);
 
      pvm_initsend(PvmDataDefault);
      sprintf(string,"Jestem %d dostalem ponownie token %d ciagle SK",mytid,token);
          pvm_pkstr(string);
      pvm_send(master_tid,MSG_SLV);
       }   
       time(&time2);
       time3=time3-(time2-time1);
    }
 
           pvm_initsend(PvmDataDefault);
       sprintf(string,"Jestem %d , wychodze z  SK",mytid);
           pvm_pkstr(string);
       pvm_send(master_tid,MSG_SLV);
}
 
int main()
{
    int mytid,who,master_tid,prevtid,nexttid,nr9;
    char my_name[NAMESIZE];
    char string[50];
    int token=0,token_recv,temp;
    int i=0;
    struct timeval t;         
    t.tv_sec=2;
    t.tv_usec=0;
 
    pvm_recv(-1,MSG_MSTR);
    pvm_upkint(&master_tid,1,1);
    pvm_upkint(&mytid,1,1);
    pvm_upkint(&nexttid,1,1);
    pvm_upkint(&prevtid,1,1);
    gethostname(my_name,NAMESIZE);
    my_name[NAMESIZE-1]=0;
    pvm_joingroup("grupa1");
 
          pvm_initsend(PvmDataDefault);
          sprintf(string,"Jestem slavem nr %d - moj poprzednik to %d - moj nastepnik to %d",mytid,prevtid,nexttid);
              pvm_pkstr(string);
          pvm_send(master_tid,MSG_SLV);
          token=false;        
          token_recv=token;
 
           if(mytid==0)
           {
          token=1-token;
              pvm_initsend(PvmDataDefault);
          sprintf(string,"Jestem slavem nr %d  zaczynam zabawe, i zmieniam token na %d",mytid,token);
              pvm_pkstr(string);
          pvm_send(master_tid,MSG_SLV);
 
 
      pvm_initsend(PvmDataDefault);
          pvm_pkint(&token,1,1);
      pvm_send(nexttid,MSG_SLV);     
           };
 
 
    pvm_barrier("grupa1",SLAVENUM);
 
while(true)
{
 
       if(temp=pvm_trecv(prevtid,MSG_SLV,&t))
   {
      pvm_upkint(&token_recv,1,1);
      pvm_initsend(PvmDataDefault);
      sprintf(string,"Jestem %d dostalem od %d token %d",mytid,(mytid+SLAVENUM-1)%SLAVENUM,token_recv);
          pvm_pkstr(string);
      pvm_send(master_tid,MSG_SLV);      
   }
 
    if(mytid==0)
    {
   if(token_recv==token)
   {
       token=!token;
       sekcja_krytyczna(master_tid,mytid,prevtid,token,timeout);
       wyslij(token,nexttid,master_tid,mytid);        
   };
    }
    else
    {
        if(token_recv!=token)
   {
       token=token_recv;
       sekcja_krytyczna(master_tid,mytid,prevtid,token,timeout);
       wyslij(token,nexttid,master_tid,mytid);
   };
    }
 
   wyslij(token,nexttid,master_tid,mytid);
 
   sleep(1);
}
    //koniec
}



Jeżeli macie jakieś pytania, postaram sie odpowiedzieć ale tak jak mówie to nie jest optymalny kod, jak znajde czas to moze cos poprawie, narazie musze zacząć robić projekt z sieci.

Pozdro
Merc

PS. w Slave : #include " " nazwe pliku zmienia na "o kurcze" Smile nie wiem czemu.

PS2. Słowo IIF też zmienia na "o kurcze" - tak samo #DEFINEE

Pliki do pobrania z [link widoczny dla zalogowanych]


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
GG
Młody forumowicz



Dołączył: 04 Gru 2006
Posty: 17
Przeczytał: 0 tematów

Ostrzeżeń: 0/5
Skąd: Malbork

PostWysłany: Pon 10:42, 04 Gru 2006    Temat postu:

Wszystko fajnie i pięknie, ale dlaczego nie mogę uruchomić moich wypocin przez ssh (putty) ???
Wywala mi błędy:

libpvm [pid646] /tmp/pvmd.22820: No such file or directory
libpvm [pid646] /tmp/pvmd.22820: No such file or directory
libpvm [pid646] /tmp/pvmd.22820: No such file or directory
libpvm [pid646]: pvm_mytid(): Can't contact local daemon
libpvm [pid646] /tmp/pvmd.22820: No such file or directory
libpvm [pid646] /tmp/pvmd.22820: No such file or directory
libpvm [pid646] /tmp/pvmd.22820: No such file or directory
libpvm [pid646]: pvm_spawn(): Can't contact local daemon
UruchomiĹem -14 procesĂłw.
libpvm [pid646] /tmp/pvmd.22820: No such file or directory

I need HELP !!!

Ograniczyłem liczbę procesów nawet do 2, ale to i tak nic nie zmienia Sad


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Mercucio
Młodszy forumowicz



Dołączył: 04 Gru 2006
Posty: 10
Przeczytał: 0 tematów

Ostrzeżeń: 0/5

PostWysłany: Pon 11:01, 04 Gru 2006    Temat postu:

Przy wklejaniu na forum podmieniły się słowa kluczowe na "o kurcze" dlatego to się nigdy nie skompiluje, wysłałem maila do roota ale jeszcze nie odpowiedział, lepiej będzie jak ściągniesz kod ze strony ( link wyżej )

Pozdro


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
GG
Młody forumowicz



Dołączył: 04 Gru 2006
Posty: 17
Przeczytał: 0 tematów

Ostrzeżeń: 0/5
Skąd: Malbork

PostWysłany: Pon 15:59, 04 Gru 2006    Temat postu:

Ja nie mówię o kompilowaniu tego co wkleiłeś (nawet nie sprawdzałem tego kodu), tylko o wykonaniu programu, który sam napisałem na zajęciach.

Na PP sie uruchamia, a przez ssh mam taki komunikat, jak podałem wcześniej. WHY???


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Mercucio
Młodszy forumowicz



Dołączył: 04 Gru 2006
Posty: 10
Przeczytał: 0 tematów

Ostrzeżeń: 0/5

PostWysłany: Pon 16:45, 04 Gru 2006    Temat postu:

Wygląda mi to na błąd demona pvm, tez tak mialem.

Spróbuj zatrzymać pvmd. Ale prawdopodobnie będziesz musiał usunąć swoje pliki od pvmd w katalogu /temp - ja musiałem

i uruchomić jeszcze raz pvm.

Aha przez ssh jest limij procesów także nie uruchamiaj za dużo, tj. żadnych procesów w tle, mc i innych edytorów bo dostaniesz - out of resources (czy jakoś tak)
u mnie (przez ssh) max procesów slave to 8.

I nie zapomnij o SETUP PVM.

A swoją drogą wkr....a mnie juz to forum, chodzi o "o kurcze" Sad

Pozdro


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
root
Administrator



Dołączył: 18 Lut 2006
Posty: 115
Przeczytał: 0 tematów

Ostrzeżeń: 0/5
Skąd: Konin

PostWysłany: Pon 23:41, 04 Gru 2006    Temat postu:

Gratuluje napisania programu !!!!!!!!!!!! Fenomen

Poza tym skad sie bierze to "O kurcze"? Nie mozna tu wkleic dobrego programu bez "O kurcze" ??

No i dodam jeszcze ze i tak ten program nam za duzo nie da... jak ktos tego nie jarzy to nie zjarzy tak, chyba ze sie z nim usiadzie na kilka godzin i mu wyjasni linijka po linijce... ehh to bedzie rzeźnia Rolling Eyes

Jeszcze raz gratulacje za napisanie i dziekuje za zamieszczenie programiku.

Marny los pozostałych ...

A moze tak kilka zdan w kwestii wyjasnienia jak program dziala - tak ogolnikowo, i o co chodzi w ogole z tym algorytmem. Moze wspolnymi siłami cos wymotamy ??


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Mercucio
Młodszy forumowicz



Dołączył: 04 Gru 2006
Posty: 10
Przeczytał: 0 tematów

Ostrzeżeń: 0/5

PostWysłany: Wto 8:37, 05 Gru 2006    Temat postu:

Witam! Mam chwilkę więc może opisze po krótce kod mastera.
Myślę że kod pierwszego listingu nie trzeba tłumaczyć?

To zaczynamy :
int mytid - zmienna w której będzie numer mastera, trzeba ją wysłać każdemu procesowi żeby mógł wysyłać do mastera wiadomości.
int tids[SLAVENUM] - tablica liczba (int) o rozmiarze podanym w osobnym pliku, w której będą numery procesów utworzonych.
char slave_name[NAMESIZE] - nazwa utworzonego procesu, u nas wszędzie "slave" bez większego znaczenia.
char napis[50] - tablica znaków ( lub jak ktoś woli "string" ) będzie służyć odbieraniu informacji od slejwów i wypisywaniu na ekran.
int nproc, i, who, last; - zwykłe liczby : pierwsza - ilość utworzonych procesów, druga potrzebna do każdej pętli, trzecia definiująca od kogo jest wiadomość do wypisania na ekran, czwarta nie robi nic Smile robiła coś we wcześniejszej wersji programu ale ten pomysł okazał się chory Smile - zapomniałem jej usunąć.

nproc=pvm_spawn(SLAVENAME, NULL, o kurcze, "", SLAVENUM, tids); - najważniejsza linijka procesu master, służy o tworzenia procesów slave, zwraca ilość poprawnie utworzonych procesów. Pierwszy parametr to nazwa każdego procesu ( u nas wszystkie mają taką samą nazwę), drugi parametr nie wiem do czego służy Sad ale musi być, trzeci oznacza standardowe ustawienia tworzonych procesów (chyba), czwarty to ilość procesów do utworzenia, piaty tablica w której będą zapisane numery każdego procesu slave.

Pierwsza pętla służy do wysłania każdemu utworzonemu procesowi potrzebnych informacji - mytid to numer mastera, każdy musi go znać żeby coś wysłać, np. żeby wypisać na ekran.
- &i nr iteracji pętli (od 0 do nproc), mówi każdemu procesowi że jest slejwem nr &i
- &tids[(i+nproc+1)%nproc] - nr procesu następnego względem tego do którego aktualnie wysyłamy. ( mówi każdemu do kogo ma wysyłać żeton - topologia pierścienia)
- &tids[(i+nproc-1)%nproc] - nr poprzedniego, czyli od kogo musi oczekiwać żetonu.
- pvm_send(tids[i], MSG_MSTR); czyli wysłanie zapakowanych informacji.

druga pętla forr to tylko mój wymysł (nie jest konieczna do działania programu) ale pokazuje informacje jakie mają procesy slave.
Każdy utworzony proces slave, zaczyna życie oczekując potrzebnych mu informacji (z poprzedniej pętli).
W tej pętli wysyła masterowi te informacje, a master wypisuje je na ekran, widać wtedy który proces na jakie informacje. Było mi to pomocne gdy program jeszcze nie działał poprawnie.

i Ostatnia pętla forr, pętla nieskończona, poprostu czeka na wiadomość od slejwa i wypisuje na ekran, dzięki temu każdy slejw co wyśle zostanie wypisane na ekranie.

Uffff to tyle, sami widzicie że to nic trudnego. postaram się znaleźć troche czasu i opisać slave.c

Narazie tyle, jutro myśle że dam rade opisać reszte slave.c - Wkurwia mnie już to "o kurcze" wszystkie słowa kluczonwe zmienia. Cały kod wkleiłem na [link widoczny dla zalogowanych]

Sorki za styl ale dziwnie sie tu edytuje.

Pozdro
Merc


Post został pochwalony 0 razy

Ostatnio zmieniony przez Mercucio dnia Wto 16:00, 05 Gru 2006, w całości zmieniany 2 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
GG
Młody forumowicz



Dołączył: 04 Gru 2006
Posty: 17
Przeczytał: 0 tematów

Ostrzeżeń: 0/5
Skąd: Malbork

PostWysłany: Wto 12:29, 05 Gru 2006    Temat postu:

Zatrzymanie pvm wywalenie z /tmp moich plików i ponowny SETUP PVM pomogło SmileSmileSmile

Dzięki. Teraz będzie można się pocić nad zrobieniem czegoś co ma ręce i nogi Sad


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Mercucio
Młodszy forumowicz



Dołączył: 04 Gru 2006
Posty: 10
Przeczytał: 0 tematów

Ostrzeżeń: 0/5

PostWysłany: Wto 15:54, 05 Gru 2006    Temat postu:

Witam ponownie!

W końcu trzeba się wziąć za kod slave.c 

Zaczynamy :

#include "def.h" // wspólny plik z definicjami kilku rzeczy
#include <sys/time.h> // plik nagłówkowy do struktury timeval

//potrzebnej przy funkcji pvm_trecv(…)

#define true 1 // definicja wartości prawdy i fałszu, która będzie wykorzystywana
#define false 0 // przy określaniu wartości tokena ( w normalnym języku, nie C, można użyć porostu typu bool )

Następnie dwa bloki kodu, określają dwie funkcje. Pierwsza będzie wysyłała token do następnego procesu w pierścieniu, lub wysyłała komunikat do mastera aby ten wypisał coś na ekranie.

Z polecenia dr Szychowiaka, funkcje które każdy proces wykonuje tak samo trzeba oddzielić od głównego programu (funkcji main) żeby poprawić czytelność  Każdy proces tak samo wysyła żeton następnemu i tak samo zachowuje się będąc w sekcji krytycznej.


void wyslij(int tok,int nexttid,int master_tid,int mytid)
// niezbędne parametry wywołania

// 1 – wartość tokena, 2 – nr następnego
// procesu, 3 – nr mastera, 4 – nr procesu
// który wywołuje funkcje.

{
int temp; // zmienna do losowego wysyłania lub nie

// będzie tam jakaś wartość

char string[50]; // tablica znaków, posłuży do wysłania masterowi komunikatu
srand(time(0)); // funkcja inicjująca wywołanie funkcji losowej rand na
temp=rand()%5; // podstawie aktualnego czasu generuje jakąś wartość

if(temp!=3) // jeżeli wygenerowana wartość jest różna od 3 to wyślij token
{
pvm_initsend(PvmDataDefault); //
pvm_pkint(&tok,1,1); // chyba nie trzeba tłumaczyć?
pvm_send(nexttid,MSG_SLV); // te trzy linie wysyłają żeton następnemu procesowi
}
else // jeżeli losowa funkcja zwróci wartość 3 to nie wysyłaj tokena, cała ta
// losowość ma posłużyć jako gubienie żetonu.
{
pvm_initsend(PvmDataDefault);
sprintf(string,"Jestem %d , NIE WYSYLAM TOKENA",mytid);
pvm_pkstr(string);
pvm_send(master_tid,MSG_SLV);
}
}
Ostatni blok skleja stringa i wysyła masterowi żeby wypisał na ekran.


Teraz funkcja która reprezentuje sekcje krytyczną, funkcja przyjmuje niezbędne parametry ( ponieważ jest zdefiniowana poza funkcją main() i nie zna wartości poszczególnych zmiennych, dlatego trzeba jest przekazać jawnie)
void sekcja_krytyczna(int master_tid,int mytid,int prevtid,int token,int time3)
{
// po kolei parametry są tak samo jak poprzednio, tylko zamiast nr nastepnego
// procesu jest nr poprzedniego, ostatni param. To czas jaki ma proces być w SK

int time1,time2,buf,temp,time4; // proste zmienne, głównie do obsługi czasu.
struct timeval time_trecv;
Wspomniana wcześniej struktura, konieczna do działania funkcji pvm_trecv(). Funkcja ta działa tak : przez podany czas ( w tej strukturze ) działa jak pvm_recv() czyli jest blokująca ( nie robi nic do czasu aż otrzyma komunikat) po upływie tego czasu (jak nic nie odbierze) program działa dalej.
char string[50]; // tak samo jak poprzednio, służy do wysłania wiadomości do mastera

time_trecv.tv_sec=time3; // to jest właśnie ta struktura, pierwsza linia to ilość sekund (nasz
time_trecv.tv_usec=0; // ostatni parametr wywołania), drugi to milisekundy.

Czyli tyle sekund ile podany przy wywołaniu funkcji, będzie blokować proces w oczekiwaniu na komunikat.
pvm_initsend(PvmDataDefault);
sprintf(string,"Jestem %d , token to %d i wchodze do SK",mytid,token);
pvm_pkstr(string);
pvm_send(master_tid,MSG_SLV);

te 4 linie oznaczaja wysłanie do mastera komunikatu żeby wyświetlił ze procesu jest w SK
while(time3>0)
{
time(&time1);
if(buf=pvm_trecv(prevtid,MSG_SLV,&time_trecv))
{
pvm_upkint(&temp,1,1);

pvm_initsend(PvmDataDefault);
sprintf(string,"Jestem %d dostalem ponownie token %d ciagle SK",mytid,token);
pvm_pkstr(string);
pvm_send(master_tid,MSG_SLV);
}
time(&time2);
time3=time3-(time2-time1);
}
ta pętla działa dopóki nie upłynie czas podany jako ostatni parametr, czyli czas jaki ma proces być w SK. Działa to tak : do zmiennej time przypisywana jest wartość aktualnego czasu na początku pętli, później zaczyna działać funkcja pvm_trecv() – blokuje na jakiś czas proces,
- jeżeli w tym czasie coś nadejdzie, ( pamiętamy ze procesy czały czas wysyłają żeton, taki jaki mają) czyli jeżeli poprzedni proces będzie wysyłał cały czas żeton, to może się zdarzyć że będąc w SK proces może otrzymywać wiadomości od poprzedniego procesu ( np. jego zeton). Jeżeli się tak zdarzy, a przewaznie się zdarzy  to trzeba go odebrać, nie może czekać w kanale bo by go „zapchał”  , odbieramy do funkcją pvm_upkint(do zmiennej tymczasowej &temp).
Nastepnie wysyłamy wiadomość masterowi żeby wypisał na ekran, że proces będący w SK otrzymał jakiś komunikat.
Nastepnie mierzony jest znowu aktualny czas.
Trzeba teraz obliczyć ile czasu już byliśmy w SK robimy to poprzez odjęcie od całego czasu jaki mamy być w SK czasu jaki byliśmy ( poprzez wartość zapisaną na początku pętli i przed chwilą ).
Jeżeli ten czas jeszcze nam został to ponownie wchodzimy do tej pętli.
Jeżeli nie to wysyłamy komunikat masterowi że wychodzimy z SK.

pvm_initsend(PvmDataDefault);
sprintf(string,"Jestem %d , wychodze z SK",mytid);
pvm_pkstr(string);
pvm_send(master_tid,MSG_SLV);
}

To ten komunikat.

Nie jest to trudne prawda?

JESZCZE RAZ OSTRZEGAM ZE NIE JEST TO OPTYMALNY KOD, A JA NIE JESTEM PROGRAMISTĄ !!!!!



Pozdro
Merc


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
root
Administrator



Dołączył: 18 Lut 2006
Posty: 115
Przeczytał: 0 tematów

Ostrzeżeń: 0/5
Skąd: Konin

PostWysłany: Wto 19:53, 05 Gru 2006    Temat postu:

Temat O KURCZE rozwiazany. Juz nie ma OKURCZE nigdzie. Prosze teraz sprobowac skompilowac powyzszy program - bez OKURCZE Cool

A poza tym wielkie dzieki za opisanie programu. Jednak istnieja "LUDZIE" u nas na roku Cool


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Mercucio
Młodszy forumowicz



Dołączył: 04 Gru 2006
Posty: 10
Przeczytał: 0 tematów

Ostrzeżeń: 0/5

PostWysłany: Śro 10:03, 06 Gru 2006    Temat postu:

Witam!

Ostatnia część. Funkcja main() programu slave.c
Kod:

    int mytid,who,master_tid,prevtid,nexttid;
    char my_name[NAMESIZE];
    char string[50];
    int token=0,token_recv,temp;
    int i=0;
    struct timeval t;
    t.tv_sec=2;
    t.tv_usec=0;


deklaracja zmiennych : mytid - nr każdego procesu ( jego własny ), who - nie potrzebn ( zapomniałem usunąć ), master_tid - chyba wiadomo? nr mastera, potrzebny żeby wysyłać wiadomości, które mają być wypisane na ekranie, przevtid, nexttid - nr odpowiednio poprzedniego i następnego procesu.
char my_name[] - tablica przechowująca imię, u nas wszystkie procesy nazywają się SLAVE
char string[] tablica w której będą informacje do wypisania na ekran;
int token - aktualna wartość tokena.
token_recv - wartość odebrana od poprzedniego procesu, później trzeba sprawdzić jak się ma do tokena jakiego każdy proces posiada. ( opis dalej)
temp - też nie potrzebna, zapomniałem usunąć.
i - to samo co wyżej.
Kod:

    struct timeval t;
    t.tv_sec=2;
    t.tv_usec=0;

Te linie powinny wyglądać znajomo. Taka sama struktura jak w przypadku funkcji sekcja_krytyczna(), potrzebna do określenia długości działania funkcji pvm_trecv() (dokładniej długości blokowania się tej funkcji).

dobra dalej ...

Kod:
    pvm_recv(-1,MSG_MSTR);
    pvm_upkint(&master_tid,1,1);
    pvm_upkint(&mytid,1,1);
    pvm_upkint(&nexttid,1,1);
    pvm_upkint(&prevtid,1,1);
    gethostname(my_name,NAMESIZE);
    my_name[NAMESIZE-1]=0;
    pvm_joingroup("grupa1");

Tak jak pisałem na początku, program slave, zaczyna działanie od zablokowania się i oczekiwania ( funkcja pvm_recv() ) na wiadomość od mastera o potrzebnych informacjach typu - master_tid, mytid, nexttid, prectid, my_name - bez tych informacji program nie działał by, bo nie wiedziałby gdzie wysłać żeton, gdzie kompunikat, od kogo oczekiwać żetonu itp.
Ostatnia linia to mój wymysł ( nie jest niezbędna do działa programu ), powoduje że dany proces dołącza się do grupy o nazwie "grupa1", dalej wyjaśnie dlaczego.

Kod:
    pvm_initsend(PvmDataDefault);
    sprintf(string,"Jestem slavem nr %d - moj poprzednik to %d - moj nastepnik to %d",mytid,prevtid,nexttid);
    pvm_pkstr(string);
    pvm_send(master_tid,MSG_SLV);
    token=false;
    token_recv=token;


O trzymaniu wszystkich niezbędnych informacji proces się "przedstawia" czyli wysyła do mastera kim jest ( w zasadzie którym procesem jest ) i jakie ma informacje. Pakuje wszystko do tablicy znaków string i wysyła.
Dalej każdy proces ustawia swój token na false ( na początku kodu slave.c jest definicja pojęcia false - czyli jest to po prostu 0 ). Tak samo z zmienną token_recv.

Kod:
    if(mytid==0)
    {
        token=1-token;
        pvm_initsend(PvmDataDefault);
        sprintf(string,"Jestem slavem nr %d zaczynam zabawe, i zmieniam token na %d",mytid,token);
        pvm_pkstr(string);
        pvm_send(master_tid,MSG_SLV);

        pvm_initsend(PvmDataDefault);
        pvm_pkint(&token,1,1);
        pvm_send(nexttid,MSG_SLV);
    };


Tą część kodu wykonuje tylko proces slave, który ma nr 0, czyli pierwszy utworzony, u nas będzie to proces zmieniający token.
Właśnie w pierwszej linii wydać ze zmienia token na "true" ( czyli 1 ), po czym wysyła komunikat do mastera, o tym co zrobił, żeby ten wypisał na ekran.
Kolejne trzy instrukcje powodują wysłanie zmienionego już tokena do następnego procesu ( czyli do procesu nr 1 ). Czyli zaczęcie zabawy z tokenem.
Kod:
    pvm_barrier("grupa1",SLAVENUM);

Ta instrukcja też nie jest konieczna do działania programu, ale ja ją dałem, powoduje że wszystkie procesy ( z grupy - skąd wcześniej definicja grupy ) dojdą do tego miejsca i zaczekają aż wszystkie procesy tu będą. Taka mini synchronizacja.

Teraz główna nieskończona pętla

Kod:
        if(temp=pvm_trecv(prevtid,MSG_SLV,&t))
        {
            pvm_upkint(&token_recv,1,1);
            pvm_initsend(PvmDataDefault);
            sprintf(string,"Jestem %d dostalem od %d token %d",mytid,(mytid+SLAVENUM-1)%SLAVENUM,token_recv);
            pvm_pkstr(string);
            pvm_send(master_tid,MSG_SLV);
        }


Pierwszą rzeczą jest wywołanie funkcji pvm_trecv() która zablokuje proces na pewien czas ( ustawiony wcześniej w odpowiedniej strukturze "t" ). Działa ona tak, czeka ustaloną ilość czasu czy otrzyma jakiś komunikat od poprzedniego procesu.
1. Jeżeli tak to rozpakuje tą wartość do zmiennej token_recv i wyśle komunikat to mastera, żeby wypisał info że proces taki otrzymał taką wartość żetonu.
2. Jeżeli przez jakiś czas nie otrzyma komunikatu to przejdzie dalej.

Kod:
        if(mytid==0)
        {
            if(token_recv==token)
            {
                token=!token;
                sekcja_krytyczna(master_tid,mytid,prevtid,token,timeout);
                wyslij(token,nexttid,master_tid,mytid);
            };
        }

Teraz jeżeli proces jest procesem nr 0 ( czyli u nas uprzywilejowanym ) to sprawdzi czy token jaki dostał jest równy temu jaki wysłał, jeżeli tak to oznacza że token przeszedł już cały pierścień, i wrócił do niego, w takim wypadku zmieni jego wartość na przeciną, czyli z true na false lub odwrotnie. Wywoła funkcje sekcja_krytyczna ( omówioną wcześniej ) po czym wyśle token ( nowy, zmieniony ) następnemu procesowi. Czyli zacznie nowy przebieg tokenu po pierścieniu.

Jeżeli proces nie jest jest procesem uprzywilejowanym,
Kod:
         else
        {
            if(token_recv!=token)
            {
                token=token_recv;
                sekcja_krytyczna(master_tid,mytid,prevtid,token,timeout);
                wyslij(token,nexttid,master_tid,mytid);
            };

        }

to sprawdza czy otrzymany (ostatnio, nie koniecznie w tym przebiegu pętli) token_recv jest inny niż token który posiada. Jeżeli tak to zmienia swój token na taki jaki przyszedł ( tak naprawdę na przeciwny, bo tylko dwie wartości tokena są dostępne) i wchodzi do SK ( czyli wywołuje funkcję sekcja_krytyczna() ), i po wyjściu z niej wysyła token następnemu.

Jeżeli żaden ze sprawdzanych warunków nie zaszedł, bo na przykład padł kanał między nim a poprzednim procesem, albo dostał token taki sam jaki miał czyli to jest ten sam obieg pętli w którym jest, to wysyła taki token jaki ma następnemu, czeli retransmituje go.

Kod:
        wyslij(token,nexttid,master_tid,mytid);


Dalej dałem jeszcze funkcje usypiającą go na sekunde, oczywiście nie jest ona niezbędna ale poprawia czytelność wyników.

To wszytko!

Nic trudnego nie?

Pozdro
Merc


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Smigacz
Stary forumowicz



Dołączył: 18 Lut 2006
Posty: 68
Przeczytał: 0 tematów

Ostrzeżeń: 0/5
Skąd: Poznań

PostWysłany: Śro 18:59, 06 Gru 2006    Temat postu:

jak dla mnie wymiatasz gościu! szacuneczek!!! Wink

Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
zn
Młody forumowicz



Dołączył: 11 Lis 2006
Posty: 22
Przeczytał: 0 tematów

Ostrzeżeń: 0/5

PostWysłany: Czw 10:22, 28 Gru 2006    Temat postu:

Proszę o pomoc! Nie moge nic skompilowac (nie zalacza mi biblioteki pvm3.h) i nie dziala mi polecenie SETUP PVM. Czy kots moze wskazać mi przyczyne tych bledow?

Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
szyni
Stary forumowicz



Dołączył: 13 Cze 2006
Posty: 62
Przeczytał: 0 tematów

Ostrzeżeń: 2/5

PostWysłany: Czw 13:46, 28 Gru 2006    Temat postu:

zn napisał:
Proszę o pomoc! Nie moge nic skompilowac (nie zalacza mi biblioteki pvm3.h) i nie dziala mi polecenie SETUP PVM. Czy kots moze wskazać mi przyczyne tych bledow?


to może napisz coś o błedach jaikie się wyświetlają?


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
zn
Młody forumowicz



Dołączył: 11 Lis 2006
Posty: 22
Przeczytał: 0 tematów

Ostrzeżeń: 0/5

PostWysłany: Czw 15:15, 28 Gru 2006    Temat postu:

Oto co mi wyswietla:
Kod:

In file included from master.c:1:
def.h:3:18: error: pvm3.h: Nie ma takiego pliku ani katalogu
master.c: In function 'main':
'PvmTaskDefault' undeclared ( first use in the function)
(Each undeclared identifier is reported only once
for each function it appears in.)
'PumDataDefault' unbdeclared ( first use in the function)

Nie jestem za bardzo obeznany w temacie, dopiero wczoraj zaczalem konfigurowac srodowisko i chyba nie do konca to dobrze zrobilem:)
Wydaje mi sie ze cos jest zle ze zmiennymi srodowiskowymi, nie wiem dokladnie jakie i jak te zmienne musza byc ustawione?
Nie pamietam tez do czego sluzylo to polecenie SETUP PVM ?


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Wyświetl posty z ostatnich:   
Napisz nowy temat   Odpowiedz do tematu    Forum SUM na Politechnice Poznańskiej, SKiSR Strona Główna -> SW Wszystkie czasy w strefie EET (Europa)
Idź do strony 1, 2  Następny
Strona 1 z 2

 
Skocz do:  
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach

fora.pl - załóż własne forum dyskusyjne za darmo
Powered by phpBB © 2001, 2005 phpBB Group
Regulamin