Τμήμα Μηχανικών Πληροφορικής Τ.Ε. Σχολή Τεχνολογικών Εφαρμογών Ακαδημαϊκό έτος 2016-2017 ΤΕΙ Ηπείρου - Άρτα Κατανεμημένα και Παράλληλα Συστήματα (εργαστήριο) Γκόγκος Χρήστος Εκφωνήσεις ασκήσεων εργαστηρίου 1 Άσκηση 1 Τι πρόκειται να εμφανίσει ο ακόλουθος κώδικας; Χρησιμοποιήστε δικά σας αναγνωριστικά διεργασιών. int main(){ pid_t chid1 = fork(); pid_t chid2 = fork(); printf("hello from process %d\n", getpid()); Άσκηση 2 Τι πρόκειται να εμφανίσει ο ακόλουθος κώδικας; int main(int argc, char** argv){ int x = 5; printf("a. value of x is %d\n", x); pid_t chid=fork(); x++; printf("b. value of x is %d\n", x); else { x--; printf("c. value of x is %d\n", x); printf("d. value of x is %d\n", x); Άσκηση 3 Να γράψετε πρόγραμμα που να δημιουργεί μια διεργασία παιδί. Η διεργασία γονέας να υπολογίζει το άθροισμα των ακεραίων από το 1 μέχρι το 100 και να το εμφανίζει ενώ η διεργασία παιδί να υπολογίζει το άθροισμα των ακεραίων από το 101 μέχρι το 200 και να το εμφανίζει. Στη συνέχεια με τη χρήση pipeline το παιδί να στέλνει το αποτέλεσμα που
υπολόγισε στο γονέα και ο γονέας να εμφανίζει την τιμή που έλαβε και το άθροισμα και των δύο συνόλων που υπολογίστηκαν. Η έξοδος του προγράμματος να είναι όπως η ακόλουθη: Computed sum by parent process is 5050 Computed sum by child process is 15050 Parent receives value 15050 from child The total sum is 20100 Άσκηση 4 Να γράψετε πρόγραμμα που να δημιουργεί μια νέα διεργασία η οποία να καλεί την εντολή ls. Τοποθετήστε εντολές printf που να εμφανίζουν ότι καλείται ο κώδικας της διεργασίας γονέα και της διεργασίας παιδί. Άσκηση 5 Να γράψετε πρόγραμμα που να δέχεται ως παράμετρο γραμμής εντολών έναν ακέραιο αριθμό. Το πρόγραμμα να δημιουργεί μια διεργασία παιδί η οποία να εξετάζει αν η παράμετρος είναι άρτια ή περιττή. Η διεργασία παιδί να τερματίζει με την εντολή exit επιστρέφοντας την τιμή 0 αν η παράμετρος είναι άρτια αλλιώς να επιστρέφει την τιμή 0. Η διεργασία γονέας να διαβάζει την τιμή που επιστρέφει η διεργασία παιδί και να την εμφανίζει. Άσκηση 6 Να γράψετε πρόγραμμα που να δέχεται ως παράμετρο γραμμής εντολών έναν ακέραιο αριθμό και να εμφανίζει το άθροισμα όλων των θετικών ακεραίων που είναι μικρότεροι ή ίσοι του αριθμού αυτού. Γράψτε δεύτερο πρόγραμμα που να μοιράζει το φόρτο υπολογισμού του αθροίσματος σε 2 διεργασίες. Μετρήστε με την εντολή time το χρόνο εκτέλεσης των δύο εναλλακτικών λύσεων για τον υπολογισμό του αθροίσματος των πρώτων 7.000.000.000 ακέραιων αριθμών. Άσκηση 7 Σε έναν κύκλο με ακτίνα r η επιφάνεια του είναι πr 2 ενώ η επιφάνεια του περιγεγραμμένου στον κύκλο τετραγώνου είναι 4r 2. Εξετάζοντας το λόγο της επιφάνειας του κύκλου προς την επιφάνεια του τετραγώνου προκύπτει ότι θα πρέπει να ισούται με π/4. Αν πραγματοποιηθεί ένα πείραμα στο οποίο θα μετρούνται πόσα από ένα σύνολο τυχαίων σημείων πέφτουν εντός του κύκλου τότε ο λόγος του πλήθους των τυχαίων σημείων εντός του κύκλου προς το συνολικό πλήθος σημείων θα πρέπει και αυτός να ισούται με π/4. Να γράψετε πρόγραμμα που να υπολογίζει χρησιμοποιώντας τον τρόπο που αναφέρθηκε τον αριθμό π. Επεκτείνατε το πρόγραμμα έτσι ώστε να μοιράζει την εργασία σε δύο διεργασίες έτσι ώστε ο υπολογισμός της εκτίμησης του π να ολοκληρώνεται ταχύτερα για μεγάλο αριθμό σημείων. Δοκιμάστε τα προγράμματα για πλήθος 300.000.000 σημείων
Λύσεις Άσκηση 1 hello from process 1038 hello from process 1040 hello from process 1039 hello from process 1041 Άσκηση 2 A. value of x is 5 C. value of x is 4 D. value of x is 4 B. value of x is 6 D. value of x is 6 Άσκηση 3 #include <sys/wait.h> int main(){ int fd[2]; pipe(fd); pid_t chid = fork(); int sum=0; for (int i=101;i<=200;i++) printf("computed sum by child process is %d\n", sum); write(fd[1], &sum, sizeof(sum)); else { int sum=0; for (int i=1;i<=100;i++) printf("computed sum by parent process is %d\n", sum); int val; read(fd[0], &val, sizeof(val)); printf("parent receives value %d from child\n", val); printf("the total sum is %d\n", sum + val);
Άσκηση 4 #include <sys/wait.h> int main(){ pid_t chid=fork(); printf("child process\n"); execl("/bin/ls", "ls", NULL, NULL); else { printf("parent process\n"); wait(null); Άσκηση 5 int main(int argc, char* argv[]){ if (argc!= 2) pid_t chid=fork(); int x = atoi(argv[1])%2; exit(x); int rv; pid_t childid = wait(&rv); printf("parent got value %d from child with id %d\n", WEXITSTATUS(rv), childid); Άσκηση 6 // gcc fork_exercise06a.c -o fork_exercise06a -std=c99 -Wall -Werror int main(int argc, char *argv[]) { if (argc!= 2) { printf("wrong number of arguments, usage: <exe> <upto>\n"); long long i, upto, sum; upto = atoll(argv[1]); sum = 0;
for (i = 0; i <= upto; i++) { printf("the sum is %lld\n", sum); time./fork_exercise06a 7000000000 // gcc fork_exercise06b.c -o fork_exercise06b -std=c99 -Wall -Werror int main(int argc, char *argv[]) { if (argc!= 2) { printf("wrong number of arguments, usage: <exe> <upto>\n"); long long i, upto = atoll(argv[1]), sum = 0; int fd[2]; pipe(fd); pid_t chid = fork(); if (chid == 0) { for (i = 0; i <= upto / 2; i++) { write(fd[1], &sum, sizeof(sum)); else { for (i = upto / 2 + 1; i <= upto; i++) { wait(null); long long sum_child; read(fd[0], &sum_child, sizeof(sum_child)); printf("the sum is %lld\n", sum + sum_child); time./fork_exercise06b 7000000000 #include <time.h>
#include <math.h> #define r 10.0 int main(int argc, char** argv){ if (argc!=2){ printf("wrong number of arguments, Usage: <exe> <number_of_points>\n"); int points = atoi(argv[1]); srand(time(null)); int c = 0; for(int i=0;i<points;i++){ double x = (double) rand()/rand_max*2*r - r; double y = (double) rand()/rand_max*2*r - r; double d = sqrt(x*x + y*y); if (d<r) c++; // printf("%.2f, %.2f %.2f\n", x,y,d); double pi = (double)c / (double)points * 4; printf("pi estimation %f vs %f\n",pi, M_PI); fork_exercise07a.c #include <time.h> #include <math.h> #define r 10.0 int count_points_inside_circle(int N){ int c = 0; for(int i=0;i<n;i++){ double x = (double) rand()/rand_max*2*r - r; double y = (double) rand()/rand_max*2*r - r; double d = sqrt(x*x + y*y); if (d<r) c++; return c;
int main(int argc, char** argv){ if (argc!=2){ printf("wrong number of arguments, Usage: <exe> <number_of_points>\n"); int fd[2]; pipe(fd); int points = atoi(argv[1]); pid_t chid = fork(); srand(time(null)); int c1 = count_points_inside_circle(points/2); write(fd[1],&c1, sizeof(c1)); else { int c2 = count_points_inside_circle(points/2); wait(null); int c1; read(fd[0],&c1, sizeof(c1)); double pi = (double) (c1+c2) / (double)points * 4; printf("pi estimation %f vs %f\n",pi, M_PI); fork_exercise07b.c