Przetwarzanie współbieżne |
---|
Wojciech Kupczyk 94415 |
Cele laboratorium:
przeprowadzenie pomiaru czasu CPU i zegarowego tworzenia procesów i wątków systemowych Linuxa
nabycie umiejętności posługiwania się programami wykorzystującymi tworzenie wątków i procesów
Zrealizowane zadania: 1-6
Ad. 3. Pliki źródłowe zostały uzupełnione o funkcję pomiaru czasu, a następnie przeprowadzono eksperyment tworzenia 1000 procesów i wątków. Poniżej fragment kodu clone.c i fork.c
inicjuj_czas(); for(i=0;i<1000;i++){ pid = clone( &funkcja_watku, (void *) stos+ROZMIAR_STOSU, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM, 0 ); waitpid(pid, NULL, __WCLONE); } printf("Proces nadrzedny: proces potomny zakonczyl dzialanie\n"); printf("Proces nadrzedny: zmienna globalna = %d\n", zmienna_globalna); drukuj_czas(); |
inicjuj_czas(); for(i=0;i<1000;i++){ pid = fork(); if(pid==0){ zmienna_globalna++; printf("Proces potomny: zmienna globalna = %d\n", zmienna_globalna); exit(0); } else { wait(NULL); printf("Proces nadrzedny: proces potomny zakonczyl dzialanie\n"); printf("Proces nadrzedny: zmienna globalna = %d\n", zmienna_globalna); } } drukuj_czas(); |
---|
clone.c fork.c
Ad. 4. Kody programów zostały zmodyfikowane tak, aby wyświetlały imię, nazwisko i PID procesu.
int funkcja_watku( void* argument ) { zmienna_globalna++; int wynik; wynik=execv("./program",NULL); if(wynik==-1) printf("Proces potomny nie wykonal programu\n"); printf("Proces potomny: zmienna globalna = %d\n", zmienna_globalna); return 0; } (…) for(i=0;i<1000;i++){ pid = clone( &funkcja_watku, (void *) stos+ROZMIAR_STOSU, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM, 0 ); waitpid(pid, NULL, __WCLONE); } |
for(i=0;i<1000;i++){ pid = fork(); if(pid==0){ zmienna_globalna++; printf("Proces potomny: zmienna globalna = %d\n", zmienna_globalna); wynik=execv("./program",NULL); if(wynik==-1) printf("Proces potomny nie wykonal programu\n"); exit(0); } else { wait(NULL); printf("Proces nadrzedny: proces potomny zakonczyl dzialanie\n"); printf("Proces nadrzedny: zmienna globalna = %d\n", zmienna_globalna); } |
---|
clone.c fork.c
int main() { printf("PID: %d\t Imie: Wojciech\t Nazwisko: Kupczyk\n", getpid()); exit(0); } |
---|
Program.c
Ad. 5. Aby funkcja clone() odpowiadała funkcji fork() należy nadać odpowiednie flagi. Wywołanie clone(0,SIGCHLD|COPYVM) jest równoważne fork-owi. W przypadku naszego programu wywołanie clone jest następujące:
clone( &funkcja_watku, (void *) stos+ROZMIAR_STOSU,SIGCHLD, 0 );
Ad. 6. Znaczenie flag przy funkcji clone jest następujące:
CLONE_VM: procesy będą współdzielić deskryptor pamięci i tablice stron. W szczególności, zmiany dokonane np. przez proces potomy będą widziane przez proces macierzysty.
CLONE_FS: procesy będą współdzielić struktury opisujące informacje o systemie plików - katalog główny i roboczy, umask. Każda operacja chroot(), chdir() czy umask() wpływa także na drugi proces współdzielący.
CLONE_FILES: procesy współdzielą tablicę deskryptorów plików - każda zmiana w jednym procesie wpływa także na drugi proces.
CLONE_SIGHAND: procesy współdzielą tablicę procedur obsługi sygnałów (signal handlers). Każda zmiana dokonana przy pomocy sigaction() jest widoczna w drugim procesie; jednak procesy mają oddzielne maski sygnałów i wywołanie sigprocmask() w jednym procesie nie wpływa na drugi proces współdzielący.
CHILD_STACK: wskaźnik stosu użytkownika dla nowego procesu.