Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

pl:dydaktyka:unix:lab_prog_system [2016/12/15 09:05]
kkutt [Ćwiczenie: Podstawy pracy z procesami]
pl:dydaktyka:unix:lab_prog_system [2019/06/27 15:50]
Linia 1: Linia 1:
-====== Elementy programowania systemowego w środowisku Unix ====== 
- 
-<WRAP center round info 60%> 
-Osoby obecne na zajęciach w poniedziałek 12.12.2016 o godz. 8:00, na których nie działało laboratorium,​ mogą wysyłać rozwiązania zadań na maila [[kkutt@agh.edu.pl]]. Liczba plusów za przesłanie N zadań to N-1. Maksymalnie można otrzymać **4 plusy** 
- --- //​[[kkutt@agh.edu.pl|Krzysztof Kutt]] 2016/12/12 11:52// 
-</​WRAP>​ 
- 
- 
-<​code>​ 
-better !pout !cry 
-better watchout 
-lpr why 
-santa claus town 
- 
-cat /etc/passwd >list 
-ncheck list 
-ncheck list 
-cat list | grep naughty >​nogiftlist 
-cat list | grep nice >​giftlist 
-santa claus  town 
- 
-who | grep sleeping 
-who | grep awake 
-who | egrep '​bad|good'​ 
-for (goodness sake) { 
-be good 
-} 
- 
-/* Nadesłał: Jakub Pelczar, IS 2012 */ 
-</​code>​ 
- 
-===== DO PRZYGOTOWANIA ===== 
-  * Proszę przypomnieć sobie, w jaki sposób kompiluje się programy w języku C w środowisku Unix \\ (np. [[http://​home.agh.edu.pl/​~gjn/​dydaktyka/​UGLX/​node10.html|Kompilacja programów w środowisku Unix]]). 
-  * Proszę przejrzeć manual do funkcji systemowych:​ **''​open(2)''​**,​ **''​creat(2)''​**,​ **''​read(2)''​**,​ **''​write(2)''​**,​ **''​stat(2)''​**,​ **''​close(2)''​**,​ \\ jak również manuale do funkcji: **''​getenv(3)''​**,​ **''​putenv(3)''​**,​ **''​setenv(3)''​** oraz do zmiennych: **''​errno(3)''​**,​ **''​environ(7)''​**. 
-===== WPROWADZENIE ===== 
- 
- 
-==== Temat: Podstawowe operacje na plikach ==== 
- 
- 
-Uwaga! przed korzystaniem z podręcznika można przełączyć go na język polski: 
- 
-  export LANG=pl_PL 
- 
-lub angielski 
- 
-  export LANG=en_EN 
- 
-Uwaga! sformułowanie typu ,,​przeczytać w manualu opis command(x)''​ oznacza, że należy wpisać: 
- 
-  man x command 
- 
-np.: ,,​przejrzeć podręcznik do funkcji //​creat(2)//'':​ 
- 
-  man 2 creat 
- 
-    
-===  Deskryptory plików === 
- 
-W systemie Unix dostęp do danych realizowany jest przez pliki. Dostęp procesów do samych plików jest realizowany przez deskryptory plików. Każdy proces ma pulę 20 deskryptorów (0-19), które mogą być przypisane do plików, potoków, itp. Deskryptory są używane we wszystkich funkcjach operujących na plikach. Deskryptor jest reprezentowany przez typ ''​int''​. 
- 
-    
-===  Tworzenie pliku === 
- 
-Proszę przejrzeć podręcznik do funkcji //​creat(2)//​. Jak wywołuje się funkcję, co funkcja zwraca? 
- 
-    
-===  Otwarcie pliku === 
- 
-Funkcja //creat()// jest szczególnym przypadkiem //open()//. 
- 
-Proszę przejrzeć podręcznik do funkcji //​open(2)//​. Jak wywołuje się funkcję, co funkcja zwraca? 
- 
-    
-===  Czytanie z pliku === 
- 
-Proszę przejrzeć podręcznik do funkcji //​read(2)//​. Jak wywołuje się funkcję, co funkcja zwraca? 
- 
-    
-===  Zapis do pliku === 
- 
-Proszę przejrzeć podręcznik do funkcji //​write(2)//​. Jak wywołuje się funkcję, co funkcja zwraca? 
- 
-    
-===  Zamknięcie pliku === 
- 
-Proszę przejrzeć podręcznik do funkcji //​close(2)//​. Jak wywołuje się funkcję, co funkcja zwraca? 
- 
-==== Temat: Zaawansowane operacje na plikach ==== 
- 
- 
-System udostępnia kilka funkcji oferujących zaawansowane operacje na plikach. 
- 
-Do zarządzania prawami dostępu służą np.: //​chmod(2)//,​ //​chown(2)//​. 
- 
-Funkcje //​access(2)//,​ //​lseek(2)//,​ czy //link(2)// zwiększają możliwości operowania na plikach. 
- 
-    
-===  Informacje o pliku === 
- 
-Proszę przejrzeć podręcznik do funkcji //​stat(2)//​. Jak wywołuje się funkcję, co funkcja zwraca? 
- 
-==== Temat: Podstawowe operacje na katalogach ==== 
- 
- 
-Katalogi implementowane są przez zwykłe pliki. Tym niemniej w systemie Unix występuje szereg funkcji upraszczających pracę z katalogami. 
- 
-Proszę przejrzeć podręcznik do funkcji //​opendir(3)//,​ //​closedir(3)//,​ //​scandir(3)//​. Jak wywołuje się te funkcje? 
- 
-==== Temat: Podstawy pracy z procesami ==== 
- 
- 
-    
-===  Środowisko === 
- 
-Proszę przejrzeć podręcznik //​environ(7)//​. 
- 
-Proszę przejrzeć podręcznik do funkcji //​getenv(3)//,​ //​putenv(3)//,​ //​setenv(3)//​. 
- 
-    
-===  Uruchamianie programu === 
- 
-Proszę przejrzeć podręcznik do funkcji //​execve(2)//​. Proszę przejrzeć podręcznik do grupy funkcji //​exec(3)//​. Funkcje z tej grupy pozwalają na uruchamianie kodu nowego programu, w obrębie już istniejącego,​ bieżącego procesu. Jak wywołuje się funkcje? Czym się różnią? 
- 
-Nie należy mylić działania tych funkcji z działaniem funkcji //​system(3)//,​ która uruchamia zewnętrzne polecenie. 
- 
-    
-=== Tworzenie nowego procesu === 
- 
-Do tworzenia nowego procesu służy funkcja //fork()//. Tworzy ona proces potomny będący kopią procesu macierzystego,​ która dziedziczy jego środowisko pracy. 
- 
-Proszę przejrzeć podręcznik do funkcji //​fork(2)//​. Jak wywołuje się funkcję, co funkcja zwraca? 
- 
-===== ĆWICZENIA ===== 
- 
- 
-====  Ćwiczenie: Podstawowe operacje na plikach ==== 
- 
- 
-W ćwiczeniu będą wykorzystywane przygotowane programy. 
- 
-  - Proszę skopiować treść programów ze strony 
- 
-Proszę oglądnąć poniższy program. 
- 
-Program //f1.c//: 
-<code c f1.c> 
-#include <​stdio.h>​ 
-#include <​fcntl.h>​ 
-#include <​unistd.h>​ 
- 
-#define BUFSIZE 1024 
- 
-int main (int argc, char **argv) { 
-    int f1, c; 
-    char b[BUFSIZE], *n1; 
- 
-    c = 10; 
-    n1 = argv[1]; 
- 
-    f1 = open (n1, O_RDONLY); 
-    read (f1, b, c); 
-    printf("​%s:​ Przeczytano %d znaków z pliku %s: \"​%s\"​\n",​ 
-    ​argv[0],​ c, n1, b); 
-    close(f1); 
- 
-    return(0); 
-} 
-</​code>​ 
- 
-skompilować go: 
- 
-  gcc -Wall -ansi -pedantic f1.c -o f1 
- 
-i uruchomić, podając jako argument stworzony wcześniej plik tekstowy. 
- 
-Należy rozbudować program o: 
- 
-    * sprawdzanie liczby argumentów wywołania 
-    * sprawdzanie rezultatu funkcji //open()// i //read()// (co powinien wypisywać //​printf()//​ jako liczbę przeczytanych znaków?) 
- 
-Proszę oglądnąć poniższy program. 
- 
-Program //f2.c//: 
- 
-<code c f2.c> 
-#include <​stdio.h>​ 
-#include <​fcntl.h>​ 
-#include <​unistd.h>​ 
-#include <​sys/​stat.h>​ 
-  
-#define BUFSIZE 1024 
- 
-int main (int argc, char **argv) { 
-    int f1, f2, c; 
-    char b[BUFSIZE], *n1, *n2; 
- 
-    c = 10; 
-    n1 = argv[1]; 
-    n2 = argv[2]; 
- 
-    f1 = open (n1, O_RDONLY); 
-    read (f1, b, c); 
-    printf("​%s:​ Przeczytano %d znaków z pliku %s: \"​%s\"​\n",​ 
-    ​argv[0],​ c, n1, b); 
- 
-    f2 = open (n2, O_WRONLY | O_CREAT | O_TRUNC, 0600); 
-    write (f2, b, c); 
-    printf("​%s:​ Zapisano %d znaków do pliku %s: \"​%s\"​\n",​ 
-    ​argv[0],​ c, n2, b); 
- 
-    close(f1); 
-    close(f2); 
- 
-    return(0); 
-} 
-</​code>​ 
- 
-skompilować go: 
- 
-  gcc -Wall -ansi -pedantic f2.c -o f2 
- 
-i uruchomić, podając jako argument stworzony wcześniej plik tekstowy i drugi plik, do którego zostaną przepisane dane. 
- 
-Należy rozbudować program o: 
- 
-    * funkcje z 1. programu, 
-    * możliwość zadania innego trybu dostępu do pliku, 
-    * możliwość kopiowania pliku dowolnej długości. 
- 
-====  Ćwiczenie: Podstawowe operacje na katalogach ==== 
- 
- 
-Proszę oglądnąć,​ skompilować i uruchomić poniższy program. 
- 
-Program //d2.c//: 
- 
-<code c d2.c> 
-#include <​stdio.h>​ 
-#include <​string.h>​ 
-#include <​sys/​types.h>​ 
-#include <​sys/​stat.h>​ 
-#include <​sys/​dir.h>​ 
- 
-#define MAX_CHAR 200 
- 
-int main(int argc, char **argv) { 
-    int t; 
-    struct direct *e; 
-    DIR *d; 
-    struct stat s; 
-    char p[MAX_CHAR];​ 
- 
-    d = opendir(argv[1]);​ 
-    while ((e = readdir(d)) != 0)  { 
- printf("​%d %s", (int)e->​d_ino,​ e->​d_name);​ 
- if (strcmp(e->​d_name,​ "​."​) != 0 && 
-     strcmp(e->​d_name,​ "​.."​) != 0) 
-     printf("​\n"​);​ 
- else { 
-     p[0] = 0; 
-     strcat(p, argv[1]); 
-     strcat(p, "/"​);​ 
-     strcat(p, e->​d_name);​ 
-     t = stat(p, &​s); ​ 
-     if (S_ISDIR(s.st_mode)) ​ 
- printf("/"​);​ 
-     printf("​\n"​);​ 
- } 
-    } 
-    closedir(d);​ 
-    return 0; 
-} 
-</​code>​ 
- 
-Jest to prymitywny program typu //ls//. 
- 
-Należy rozbudować program o: 
- 
-    * precyzyjne sprawdzanie wartości zwracanych przez funkcje, a co za tym idzie podstawową diagnostykę błędów, 
-    * jak najwięcej możliwości typu //ls//, czyli czytanie kolejnych danych zwracanych przez funkcję //stat()//, 
-    * możliwość wyświetlania zawartości podkatalogów. 
- 
-==== Ćwiczenie: Środowisko pracy procesu ==== 
- 
-Proszę oglądnąć i uruchomić poniższy program: 
- 
-Program //p1.c//: 
- 
-<code c p1.c> 
-#include <​stdio.h>​ 
-#include <​unistd.h>​ 
- 
-extern char **environ; 
- 
-int main (int argc, char **argv, char **envp) { 
-    int i; 
- 
-    printf("​Srodowisko procesu:​\n"​);​ 
-    for (i = 0; envp[i] != NULL;i++) 
- printf("​%s\n",​ envp[i]); 
- 
-    return(0); 
-} 
-</​code>​ 
- 
-Proszę zmodyfikować program, aby pozwalał na wypisywanie i zmianę wartości wybranej zmiennej środowiskowej. 
- 
-====  Ćwiczenie: Podstawy pracy z procesami ==== 
- 
- 
-Proszę oglądnąć i uruchomić poniższy program: 
- 
-Program //p2.c//: 
- 
-<code c p2.c> 
-#include <​stdio.h>​ 
-#include <​unistd.h>​ 
-#include <​stdlib.h>​ 
- 
-extern char **environ; 
- 
-int main (int argc, char **argv, char **envp) { 
- 
-    printf("​Poczatek procesu.\n"​);​ 
- 
-    system("​echo ala ma kota"​);​ 
-    printf("​Dalszy ciag kodu...\n"​);​ 
- 
-    execl("/​bin/​echo",​ "​echo",​ "jakis napis",​ NULL); 
-    printf("​Koniec kodu...\n"​);​ 
- 
-    return(0); 
-} 
-</​code>​ 
- 
-Jaka jest różnica pomiędzy funkcjami //​system()//​ a //exec()//? 
- 
-Proszę zmodyfikować program tak, aby działał tak samo przy użyciu innych wywołań z rodziny funkcji //exec()//. 
- 
-Proszę oglądnąć i uruchomić poniższy program. 
- 
-Program //p3.c//: 
- 
-<code c p3.c> 
-#include <​stdio.h>​ 
-#include <​unistd.h>​ 
- 
-extern char **environ; 
- 
-int main (int argc, char **argv, char **envp) { 
-    int p=0; 
- 
-    printf("​Poczatek procesu...\n"​);​ 
-    p = fork(); 
-    printf("​Tu jestem: %d\n", p); 
- 
-    return(0); 
-} 
-</​code>​ 
- 
-Jak działa program? Dlaczego? 
- 
-Dla lepszego zrozumienia proszę oglądnąć i uruchomić kolejny program. 
- 
-Program //p4.c//: 
- 
-<code c p4.c> 
-#include <​stdio.h>​ 
-#include <​unistd.h>​ 
-#include <​stdlib.h>​ 
- 
-extern char **environ; 
- 
-int main (int argc, char **argv, char **envp) { 
-    int p=0; 
- 
-    printf("​%s[%d]:​ Poczatek procesu glownego...\n",​ 
-    ​*argv,​ getpid()); 
-    p = fork(); 
-    if (p == -1) 
- printf("​%s[%d]:​ BLAD! Nie moge stworzyc procesu!\n",​ 
-        ​*argv,​ getpid()); 
-    else if ( p > 0) { 
- printf("​%s[%d]:​ To dalej ja, proces glowny...\n",​ 
-        ​*argv,​ getpid()); 
- sleep(5); 
-    } 
-    else if ( p == 0 ) { 
- printf("​%s[%d]:​ Jestem procesem potomnym, moj rodzic to: [%d]...\n",​ 
-        ​*argv,​ getpid(), getppid()); 
- exit (0); 
-    } 
- 
-    printf("​%s[%d]:​ Koniec procesu glownego...\n",​ 
-    ​*argv,​ getpid()); 
-    exit (0); 
-    return(0); 
-} 
-</​code>​ 
- 
-Proszę otoczyć komentarzem wywołanie funkcji //​sleep()//,​ jak to wpłynie na działanie procesów? 
- 
-Proszę oglądnąć i uruchomić poniższy program. 
- 
-Program //p5.c//: 
- 
-<code c p5.c> 
-#include <​stdio.h>​ 
-#include <​unistd.h>​ 
-#include <​stdlib.h>​ 
-#include <​sys/​wait.h>​ 
- 
-extern char **environ; 
- 
-int main (int argc, char **argv, char **envp) { 
-    int p=0,p1=0; 
- 
-    printf("​%s[%d]:​ Poczatek procesu glownego...\n",​ 
-    ​*argv,​ getpid()); 
-    p = fork(); 
-    if (p == -1) 
- printf("​%s[%d]:​ BLAD! Nie moge stworzyc procesu!\n",​ 
-        ​*argv,​ getpid()); 
-    else if ( p > 0) { 
- printf("​%s[%d]:​ To dalej ja, proces glowny...\n",​ 
-        ​*argv,​ getpid()); 
-    } 
-    else if ( p == 0 ) { 
- printf("​%s[%d]:​ Jestem procesem potomnym, moj rodzic to: [%d]...\n",​ 
-        ​*argv,​ getpid(), getppid()); 
- sleep(5); 
- printf("​%s[%d]:​ Koncze ze soba!\n",​ 
-        ​*argv,​ getpid()); 
- exit (0); 
-    } 
- 
-    p1=wait(NULL);​ 
-    printf("​%s[%d]:​ Jestem bezdzietny, nie ma juz: %d :(\n", 
-    ​*argv,​ getpid(), p1); 
- 
-    printf("​%s[%d]:​ Koniec procesu glownego.\n",​ 
-    ​*argv,​ getpid()); 
-    exit (0); 
-    return(0); 
-} 
-</​code>​ 
- 
-Procesy macierzyste mogą czekać na zakończenie potomnych. 
- 
-Proszę rozbudować powyższy program, wg. własnej inwencji. 
- 
-====  Ćwiczenie: Procesy i uruchamianie programów ==== 
- 
- 
-Proszę oglądnąć i uruchomić poniższy program. 
- 
-Program //p6.c//: 
- 
-<code c p6.c> 
-#include <​stdio.h>​ 
-#include <​unistd.h>​ 
-#include <​stdlib.h>​ 
-#include <​sys/​wait.h>​ 
- 
-extern char **environ; 
- 
-int main (int argc, char **argv, char **envp) { 
-    int p=0,p1=0; 
- 
-    printf("​%s[%d]:​ Poczatek procesu glownego...\n",​ 
-    ​*argv,​ getpid()); 
-    p = fork(); 
-    if (p == -1) 
- printf("​%s[%d]:​ BLAD! Nie moge stworzyc procesu!\n",​ 
-        ​*argv,​ getpid()); 
-    else if ( p > 0) { 
- printf("​%s[%d]:​ To dalej ja, proces glowny...\n",​ 
-        ​*argv,​ getpid()); 
-    } 
-    else if ( p == 0 ) { 
- printf("​%s[%d]:​ Jestem procesem potomnym, moj rodzic to: [%d]...\n",​ 
-        ​*argv,​ getpid(), getppid()); 
- printf("​%s[%d]:​ Moge byc kims innym!\n",​ 
-        ​*argv,​ getpid()); 
- execl("/​bin/​echo",​ "​echo",​ "moge stac sie programem ktory cos pisze!",​ NULL); 
-    } 
- 
-    p1=wait(NULL);​ 
-    printf("​%s[%d]:​ Jestem bezdzietny, nie ma juz: %d :(\n", 
-    ​*argv,​ getpid(), p1); 
- 
-    printf("​%s[%d]:​ Koniec procesu glownego.\n",​ 
-    ​*argv,​ getpid()); 
-    exit (0); 
-    return(0); 
-} 
-</​code>​ 
- 
-====  Ćwiczenie: Procesy i zrównoleglanie pracy ==== 
- 
-Proszę oglądnąć i uruchomić poniższy program. 
- 
-Program //p7.c//: 
- 
-<code c p7.c> 
-#include <​stdio.h>​ 
-#include <​unistd.h>​ 
-#include <​stdlib.h>​ 
-#include <​sys/​wait.h>​ 
-#include <​fcntl.h>​ 
-#include <​sys/​stat.h>​ 
- 
-#define BUFSIZE 1024 
-#define CPC 5 
-#define NC 5 
- 
-extern char **environ; 
- 
-int main (int argc, char **argv, char **envp) { 
-    int p=0, p1=0, f, n=5, c, i, j; 
-    char *b, *n1; 
- 
-    c = NC; 
-    n1 = argv[1]; 
- 
-    printf("​%s[%d]:​ Poczatek procesu glownego...\n",​ 
-    ​*argv,​ getpid()); 
-    f = open (n1, O_RDONLY); 
-    for (i=0; i<n; i++) { 
- p = fork(); 
- if (p == -1) 
-     printf("​%s[%d]:​ BLAD! Nie moge stworzyc procesu!\n",​ 
-    ​*argv,​ getpid()); 
- else if ( p > 0) { 
-     printf("​%s[%d]:​ To dalej ja, proces glowny...\n",​ 
-    ​*argv,​ getpid()); 
- } 
- else if ( p == 0 ) { 
-     printf("​%s[%d]:​ Jestem procesem potomnym, moj rodzic to: [%d]...\n",​ 
-    ​*argv,​ getpid(), getppid()); 
-     sleep(1); 
-     lseek(f, i*CPC, SEEK_SET); 
-     b = malloc(sizeof(char)*c+1);​ 
-     j = read (f, b, c); 
-     b[c+1]='​\n';​ 
-     printf("​%s:​ Przeczytano %d znaków, poczynajac od: %d,  z pliku %s: \"​%s\"​\n",​ 
-    ​argv[0],​ j, i*CPC, n1, b); 
-     free(b); 
-     exit(0); 
- } 
-    } 
- 
-    p1=wait(NULL);​ 
-    printf("​%s[%d]:​ Jestem bezdzietny, ostatnie dziecko to: %d :(\n", 
-    ​*argv,​ getpid(), p1); 
-    close(f); 
-    printf("​%s[%d]:​ Koniec procesu glownego.\n",​ 
-    ​*argv,​ getpid()); 
-    exit (0); 
-    return(0); 
-} 
-</​code>​ 
- 
-Ważna obserwacja: proces potomny dziedziczy środowisko,​ wraz z kopiami deskryptorów plików. 
- 
-Proszę przeanalizować i zmodyfikować powyższy program, np. tak, aby czytał inne fragmenty pliku, lub wykonywał równolegle inne operacje. 
- 
-===== BIBLIOGRAFIA ===== 
- 
-Ważne, przydatne książki: 
- 
-    * Brian W. Kernighan, Dennis M. Ritchie, //Język ANSI C (org. The C Programming Language (Second Edition))//,​ WNT, Warszawa, 1994 i następne. 
-    * Brian W. Kernighan, Rob Pike, //The UNIX Programming Environment//,​ Prentice Hall, 1984. 
-    * Marc J. Rochkind, //​Programowanie w systemie Unix dla zaawansowanych (arg. Advanced Unix Programming)//,​ WNT, Warszawa, 1997. 
-    * W. Richard Stevens, //Advanced Programming in the UNIX Environment//,​ Addison-Wesley Professional,​ 1992. 
-    * Eric S. Raymond, //The Art of UNIX Programming//,​ Addison-Wesley Professional,​ 2003. 
  
pl/dydaktyka/unix/lab_prog_system.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0