Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Dawid Mocek
- Kod przetestowany na własnym klastrze PVM(PVM_ARCH=FREEBSD). Działa. Nie zakładam istnienia obiektu typu string bo to jest C oraz nie wiem czym dokładnie jest generacja skrótu łańcuchowego(patrz kod workera/slave`a) w workerze
- */
- /*
- Zad. 2 PVM
- Napisać kod programu głównego,
- 1) uruchamiajacego na każdym dostępnym w maszynie PVM procesorze jeden proces potomny
- 2) rozdzielającego do równoległego wyliczenia, skrótu łańcuchów znakowych znajdujących się w tablicy NAPSIY. Tablica NAPISY
- posiada N wpisów w postaci łańcuchów znakowych. Dla ułatwienia przyjąć dostępność obiektu typu string.
- Założyć, iż skrót dla pojedynczego napisu wyznaczony jest przez proces potomny(którego nie należy pisać).
- Skróty poszczególnych łańcuchów w postaci wartości typu INT umieścić w programie głównym w tablicy skróty, aby ity skrót
- odnosił się do itego łańcucha
- 3) zapewnić zrównoważenie obciążenia procesów potomnych przez dynamiczny przydział zadań
- 4) zakończyć procesy potomne
- */
- /*-----------------------------------*/
- /*
- [dawid@freeone ~]$ cat kompiluj.sh
- #!/bin/sh
- /usr/local/bin/gcc47 -lpvm3 /home/dawid/pvm.c -o /home/dawid/pvm
- /usr/local/bin/gcc47 -lpvm3 /home/dawid/zadanie.c -o /home/dawid/zadanie
- echo "Kopiowanie do freetwo.com"
- scp zadanie [email protected]:~
- echo "Kopiowanie do freethree.com"
- scp zadanie [email protected]:~
- */
- /***
- * config.h
- */
- #define N 11
- #define FLAGA_ROZPOZNAWCZA_WORKERA 1111
- #define FLAGA_ROZPOZNAWCZA_MASTERA 999
- #define WORKER_PATH "/home/dawid/zadanie"
- /***
- * pvm.c
- * Dawid Mocek
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <pvm3.h>
- #include <sys/unistd.h>
- #include "config.h"
- int *podziel_na_czesci(int liczba_elementow, int liczba_hostow) {
- int i, j, k, *tab = NULL;
- tab = (int *)calloc(liczba_hostow, sizeof(int));
- // tu mamy po rowno elementow
- if ((liczba_elementow % liczba_hostow) == 0) {
- k = (liczba_elementow / liczba_hostow);
- for (i = 0; i < liczba_hostow; ++i)
- tab[i] = k;
- }
- // a tu nie
- else {
- k = liczba_elementow / liczba_hostow;
- for (i = 0; i < liczba_hostow ; ++i)
- tab[i] = k;
- tab[i - 1] += liczba_elementow - (k * liczba_hostow);
- }
- return tab;
- }
- int main(void) {
- int ilhost, ilarch, mytid, indeks, id_procesu, i, j, len, skrot, pvm_res, bytes, msgtag;
- int *nasze_procesy = NULL;
- int *ilosc = NULL;
- struct pvmhostinfo *info = NULL;
- char hostname[128];
- char *napisy[N] = { "abcff", "defggg", "ghhdfg", "isdfsdfjk", "sdflmn", "opqrst", "aabb", "ccdd", "eeff", "gguu", "hhoo" };
- int skroty[N];
- // Dla wiedzy skad gdzie co leci
- gethostname(hostname, sizeof hostname);
- // PVM
- mytid = pvm_mytid();
- // Dla debugu - lapiemy co rzygajaja spawn'owane procesy
- pvm_catchout(stdout);
- // Pobieram konfig. pvma - najwazniesza stad to ilosc hostow(ILe HOSTow) i struct info
- pvm_config(&ilhost, &ilarch, &info);
- // Musimy rozlozyc ilosc strigow jakie wysylamy w zaleznosci od ilosc hostow
- ilosc = podziel_na_czesci(N, ilhost);
- // Tu trzymamy id procesow
- nasze_procesy = (int *)calloc(ilhost, sizeof(int));
- indeks = 0;
- for(i = 0; i < ilhost; i++) {
- // Spawn`ujemy proces na remote hoscie
- printf("[%s] Spawnuje proces na hoscie: %s\n", hostname, info[i].hi_name);
- pvm_spawn(WORKER_PATH, (char **)0, PvmTaskHost, info[i].hi_name, 1, &id_procesu);
- // Zapamietuje id procesu
- printf("[%s] Numer procesu: %d @ %s\n", hostname, id_procesu, info[i].hi_name);
- nasze_procesy[i] = id_procesu;
- // Przygotowujemy sie do wysylki danych
- pvm_initsend(PvmDataDefault);
- printf("[%s] Iteracja = %d. Wysylam stringow = %d\n", hostname, i, ilosc[i]);
- // Nasz worker musi wiedziec ile pakietow do niego dojdzie
- pvm_pkint(&ilosc[i], 1, 1);
- printf("[%s] Pakuje ilosc: %d\n", hostname, ilosc[i]);
- for(j = 0; j < ilosc[i]; indeks++, j++) {
- len = strlen(napisy[indeks]);
- // Pakuje indeks tablicy **napisy
- pvm_pkint(&indeks, 1, 1);
- // Pakuje dlugosc stringa - bez nulla
- pvm_pkint(&len, 1, 1);
- // Pakuje stringa
- pvm_pkstr(napisy[indeks]);
- printf("[%s] Pakuje stringa: '%s' z pod indeksu: %d o dlugosci = %d\n", hostname, napisy[indeks], indeks, len);
- }
- // Wysylam
- pvm_send(id_procesu, FLAGA_ROZPOZNAWCZA_MASTERA);
- }
- // koniec wysylania
- // teraz czas to odebrac
- // Czekamy na rezultaty
- printf("[%s] Odbieram dane...\n", hostname);
- for(i = 0; i < N; i++) {
- // Pobieram
- pvm_res = pvm_recv(-1, -1);
- // Informacje skad odebralismy i ile
- pvm_bufinfo(pvm_res, &bytes, &msgtag, &id_procesu);
- // Sam worker musi nam opdowiedziec dwoma pakietami - indeksem i wynikiem
- printf("[%s] Dostalem bajtow: %d od procesu: %d z tagiem %d\n",hostname, bytes, id_procesu, msgtag);
- // Wypakowuje indeks:
- pvm_upkint(&indeks, 1, 1);
- // Wypakowuje wygenerowy "skrot" - czymkolwiek on jest
- pvm_upkint(&skrot, 1, 1);
- // Zapisuje
- skroty[indeks] = skrot;
- // zabijam proces
- pvm_kill(id_procesu);
- }
- // Druk wyniku
- printf("--------------------\n");
- for(j = 0; j < N; ++j)
- printf("Skrot dla: '%s' = %d\n", napisy[j], skroty[j]);
- free(nasze_procesy);
- free(info);
- free(ilosc);
- pvm_exit();
- }
- /***
- * zadanie.c
- * Dawid Mocek
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/unistd.h>
- #include <pvm3.h>
- #include "config.h"
- int main(void) {
- int mytid;
- int skrot, len, i, j, cnt;
- int indeks, master, pvm_res;
- char *str = NULL;
- char hostname[128];
- gethostname(hostname, sizeof hostname);
- // Ja
- mytid = pvm_mytid();
- // Odbieramy dane
- pvm_recv(-1, -1);
- // Ilosc pakietow
- pvm_upkint(&cnt,1 ,1);
- printf("[%s][%d] Dostalem pakietow %d.\n", hostname, mytid, cnt);
- for(j = 0; j < cnt; j++) {
- // Wypakowuje indeks
- pvm_upkint(&indeks, 1, 1);
- // Wypakowuje dlugosc stringa
- pvm_upkint(&len, 1, 1);
- // Rezerwujemy pamiec
- str = (char *)malloc((sizeof(char) * len) + sizeof(char));
- memset(str, 0, (len * sizeof(char)) + sizeof(char));
- // Wypakowuje stringa
- pvm_upkstr(str);
- printf("[%s][%d] Dostalem string: '%s' z pod indeksu: %d o dlugosc %d.\n", hostname, mytid, str, indeks, len);
- // Generujemy skrot - generalnei co zrobie to zamienie kazdy znak na int`a(procz nulla) i dodam je do siebie
- skrot = 0;
- for(i = 0; i < len; i++)
- skrot += (int)str[i];
- // Master
- master = pvm_parent();
- pvm_initsend(PvmDataDefault);
- // Pakuje indeks
- pvm_pkint(&indeks, 1, 1);
- // Pakuje skrot
- pvm_pkint(&skrot, 1, 1);
- // Wysylam
- pvm_res = pvm_send(master, FLAGA_ROZPOZNAWCZA_WORKERA);
- free(str);
- str = NULL;
- }
- pvm_exit();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement