Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Semafory Semafor w programowaniu jest abstrakcją o zastosowaniu zaczerpniętym z działalności kolei. Gdy zasobów jest na tyle mało, że trzeba ich użyciem.

Podobne prezentacje


Prezentacja na temat: "Semafory Semafor w programowaniu jest abstrakcją o zastosowaniu zaczerpniętym z działalności kolei. Gdy zasobów jest na tyle mało, że trzeba ich użyciem."— Zapis prezentacji:

1 Semafory Semafor w programowaniu jest abstrakcją o zastosowaniu zaczerpniętym z działalności kolei. Gdy zasobów jest na tyle mało, że trzeba ich użyciem się dzielić (typowych zasobów jest zawsze za mało), naturalne jest wprowadzenie znaczników zajętości. W kolejnictwie semafory informują o zajętości toru, stacji itp.. Np. jeśli dany jest pojedynczy odcinek torów na którym powinien znajdować się najwyżej jeden pociąg, inne pociągi muszą czekać, aż semafor przyjmie stan zezwalający na zajęcie tego odcinka torów. W wersji komputerowej semafor może być przechowywaną zmienną typu int. Dany proces czeka aż zmienna ta przyjmie wartość zero. Gdy proces uzyskuje dostęp do zasobu będącego chronionego semaforem, podwyższa tą wartość o jeden (inkrementuje). Gdy kończy używanie, odejmuje od tej wartości jeden.

2 Semafory semget() semctl() semop()

3 Semafory semget() Funkcja semget() inicjalizuje lub umożliwia dostęp do semaforu. Oto jej prototyp: #include int semget(key_t key, int nsems, int semflg); w przypadku sukcesu funkcja zwraca semid (semaphore id) key – wartość klucza stowarzyszona z semaforem nsems – ile elementów ma dany semafor (jego macierz) semflg – definiuje początkowe prawa dostępu, znaczniki kontrolne ( na przykład: 0666 | IPC_CREAT | IPC_EXCL )

4 Semafory semget() #include... key_t key; int semflg; int nsems; int semid; /* semafor id zwracane przez semget() */

5 Semafory semget() key =... ; nsems =... ; semflg =... ; if ((semid = semget(key, nsems, semflg)) == -1) { perror("semget: semget failed"); exit(1); } else...

6 Semafory semctl() zmienia charakterystyki danego semaforu int semctl(int semid, int semnum, int cmd, union semun arg); semid – semafor id semnum – wybór semaforu (jego indeks, np. 0,1,...) union semun { /* do operacji kontrolnych semctl() */ int val; struct semid_ds *buf; ushort_t *array; } arg;

7 Semafory semctl() cmd jest jedną z następujących wartości: GETVAL -- Zwróć wartość pojedynczego semaforu. SETVAL -- Ustaw wartość pojedynczego semaforu. Użyte jest arg.val. GETPID -- Zwróć pid procesu który wykonał ostatnią operację na tym semaforze. GETNCNT -- Zwróć liczbę procesów czekających na to, by wartość semaforu wzrosła. GETZCNT -- Zwróc liczbę procesów czekających na to, by wartość semaforu osiągnęła zero.

8 Semafory semctl() cmd jest jedną z następujących wartości: GETALL -- zwróć wartości wszystkich semaforów w danej macierzy; użyta jest arg.array. SETALL -- ustaw wartości wszystkich semaforów w danej macierzy; użyta jest arg.array. IPC_STAT -- zwrócona jest informacja o semaforze, zostaje umieszczona w strukturze danych arg.buf (czyli użyty jest obiekt typu semid_ds). IPC_SET -- Ustawione zostają parametry: uzytkownik, grupa, prawa dostępu. Zostaje użyte arg.buf. IPC_RMID -- Semafor zostanie usunięty.

9 Semafory - semop() #include /* wykonuje operacje na semaforze */ int semop(int semid, struct sembuf *sops, size_t nsops); semid -- semafor id (zwrócone przez semget() ) sops -- wskaźnik do macierzy struktur (struktura sembuf opisuje operację na semaforze) struct sembuf { ushort_t sem_num; /* numer semaforu */ short sem_op; /* kod operacji */ short sem_flg; /* znacznik operacji */ };

10 Semafory - semop() Argument nsops określa długość tej macierzy struktur; tym samym określa ile operacji wykona pojedyncze zawołanie semop(). Operacje są wykonywane w następujący sposób: dodatnia wartość int powiększa wartość semafora (o wartość) ujemna wartość int obniża wartość semafora (o wartość), próba ustawienia semafora na mniej niż zero powoduje blokowanie (zawieszenie procesu) lub błąd, w zależności od tego czy włączony jest znacznik IPC_NOWAIT wartość zero oznacza żądanie oczekiwanie aż semafor osiągnie zero

11 Semafory - semop() znaczniki kontrolne IPC_NOWAIT – zgłasza zakaz blokowania procesu (gdyby operacja nie mogła być wykonana) SEM_UNDO – poszczególne operacje opisane w macierzy struktur zostaną wycofane gdy semop() się załamie (uda się wszystko albo nic)

12 Semafory - semop() po wywołaniu semop() proces (jego dalsze wykonanie) jest blokowany (chyba że użyte jest IPC_NOWAIT); tak długo aż dojdzie do jednej z poniższych sytuacji: semop() się wykona proces otrzyma sygnał semafor zostanie usunięty (np.. komendą ipcrm, lub usunie go inny proces)

13 Semafory Uwagi: tylko jeden proces na raz może modyfikować semafor. Jeśli kilka procesów spróbuje zrobić to jednocześnie, zostaną wykonane w kolejności o której rozstrzygnie system operacyjny. Jeśli proces modyfikujący semafor padnie, może się zdarzyć że stan semaforu został zmodyfikowany tylko częściowo.

14 Semafory - przykład #include #include //fork() #include #include //semget(), semctl() #include

15 Semafory - przykład main() { int semid; key_t klucz; typedef unsigned short ushort_t; union semun { int val; struct semid_ds *buf; ushort_t *array; } sun;//do operacji kontrolnych, semctl

16 Semafory - przykład klucz = ftok(".", 110); /* ftok użyty do generacji klucza */ semid=semget(klucz, 3, 0666 | IPC_CREAT);/* tworzy zbior semaforow*/ printf("\nTworzono zbior semaforow o ID=%d\n",semid); if(semid==1) {printf(nie udalo się!\n); exit(1); } sun.val=3; semctl(semid, 0, SETVAL, sun); /*ustawienie wartosci */ sun.val=7; semctl(semid, 1, SETVAL, sun); /*ustawienie wartosci */ semctl(semid, 2, SETVAL, sun); /*ustawienie wartosci */ return 0; } /* koniec funkcji main */

17 Semafory - ipcs ipcs -s Semaphore Arrays key semid owner perms nsems status 0x6e0fc rudy 666 3

18 Semafory – przykład_2 #include // #include //key_t #include //ftok() #include //semget() struct sembuf bs = {0, 0, 0}; /* operacje */ main() { int semid, i; key_t klucz; int ktrl;

19 Semafory – przykład_2 klucz = ftok(".",110); semid = semget(klucz, 3, 0000 ); if(semid == -1) { perror("Blad otwarcia semafora\n"); return 1; } else { /* semget() OK */ printf("\n otwarto zbior semaforow o ID=%d\n\n",semid); }

20 Semafory – przykład_2 printf(" teraz proces o id=%d wypisze \ COS jesli stan semafora\n zezwoli na to\n\n",getpid()); if( (ktrl=semop(semid, &bs,1))==-1) perror(" blad semop! "); else printf("\n semop zwrocilo wartosc %d\n", ktrl); printf("proces id=%d pisze: COS COS COS COS\n", getpid()); /* to powyższe wypisanie na dowód że proces doczekał się na przyjęcie przez semafor wartości zero */ return 0; } /* koniec funkcji main */

21 Semafory w przedstawionym powyżej przykładzie proces czeka na wartość zero semafora; poniższy program obniża wartość semafora, może zatem doprowadzić do odblokowania powyższego procesu

22 Semafory – przykład_3 #include #include //rand() #include //key_t #include //ftok() #include //semget() typedef unsigned short ushort_t; struct sembuf bs = {0, -1, 0};

23 Semafory – przykład_3 union semun { int val; struct semid_ds *buf; ushort_t *array; } sun; //do operacji kontrolnych, semctl unsigned short alfa[3];

24 Semafory – przykład_3 main() { int semid, i; key_t klucz; int ktrl; klucz = ftok(".",110); semid = semget(klucz, 3, 0000 );

25 Semafory – przykład_3 if(semid == -1) { perror("Blad otwarcia semafora\n"); return 1; } else { printf("\n otwarto zbior semaforow o\ ID=%d\n\n",semid); }

26 Semafory – przykład_3 printf(" teraz proces o pid=%d opusci semafor\n\n",getpid()); /* czy opuści aż do zera ? */ if ( (ktrl=semop(semid, &bs,1))==-1) perror(" blad semop! "); else printf("\n semop zwrócilo wartosc %d\n\n", ktrl);

27 Semafory – przykład_3 sun.array = alfa; semctl(semid, 1, GETALL, sun); /*pobranie wartosci semaforów*/ for(i=0; i<3; ++i) { printf(" wartosc semafora=%d\n", *(alfa+i)); } exit(0); } /* koniec funkcji main */

29 Podsumowanie potoki (pipes, FIFO) sygnały shared memory kolejki wiadomości semafory

30 Sockets (czyli gniazda) Przy użyciu socketów buduje się dwukierunkową komunikację typu punkt-punkt pomiędzy dwoma procesami. Jest to bardzo giętki proces komunikowania się, jest podstawowoym składnikiem komunikacji pomiędzy procesami (także procesami działającymi na różnych komputerach). Socket musi być identyfikowany przez nazwę, system operacyjny tworzy dla niego jeden (lub więcej) realizujących go procesów. Sockets istnieją w przestrzeni komunikacyjnej. Taka przestrzeń to abstrakcja; ma ona mieć adresującą strukturę (adresującą w sposób jednoznaczny!) i zbiór protokołów, które korzystają z tej przestrzeni. Dwie podstawowe zrealizowane przestrzenie-domeny: UNIX i Internet (np. VMS/VAX praktycznie przestał się liczyć, sieci typu NOVELL także przeszły na TCP/IP)

31 Sockets (czyli gniazda) dygresja uucp UNIX-to-UNIX copy cu connect UNIX

32 Sockets Gniazda mogą być oczywiście zrealizowane na pojedynczym systemie. Jeśli użyte gniazdo ma łączyć różne systemy/komputery to trzeba użyć przestrzeni- domeny Internetu (protokoły typu UNIX-to-UNIX praktycznie nie są już używane). krótka dygresja o wspólnym kablu....kiedyś w budynku przy ul. Reymonta 4....

33 Sockets Rodzaj gniazda (socketu) określa jak komunikacja jest wykonywana stream socket tryb połączeniowy. Określa dwustronny, z korekcją błędów przepływ danych, nieduplikowany. Pracuje podobnie jak rozmowa telefoniczna. Typem gniazda jest SOCK_STREAM, używany jest Transmission Transfer Protocol (TCP); czyli dla internetu jest to łącznie TCP/IP. datagram socket tryb bezpołączeniowy. Gniazdo może otrzymać dane w sekwencji innej niż sekwencja wysyłana. Datagramy są duplikowane, jeśli nie zostało otrzymane potwierdzenie, że dotarły. Wymiana informacji jest realizowana jak wysyłanie listów tam i z powrotem. Typem gniazda jest SOCK_DGRAM, używany jest User Datagram Protocol (UDP), czyli dla internetu jest to łącznie UDP/IP.

34 Sockets int socket(int domain, int type, int protocol) Funkcja tworzy gniazdo w wybranej domenie(PF_INET, PF_UNIX) o określonym type (SOCK_STREAM lub SOCK_DGRAM). Jeśli protokól nie jest podany, system operacyjny sam dobierze protokół obsługujący daną domenę i dany typ gniazda. Funkcja zwraca deskryptor do procesu obsługującego gniazdo (socket handler). Inny proces nie może zidentyfikować gniazda dopóki do gniazda nie zostanie przywiązany adres. Procesy mogą komunikować się przez gniazda z przypisanymi adresami: w Internecie gniazdo z przypisanym adresem to inaczej port.

35 Sockets man socket podaje jeszcze np. : PF_UNIX,PF_LOCAL Local communication PF_INET IPv4 Internet protocols PF_IPX IPX - Novell protocols PF_X25 ITU-T X.25 / ISO-8208 protocol PF_AX25 Amateur radio AX.25 protocol PF_APPLETALK Appletalk

36 Sockets int bind(int s, struct sockaddr *name, int namelen) funkcja przywiązuje adres do gniazda (ten adres to ścieżka do pewnego pliku który można zobaczyć jako jeden z plików używając komendy ls –l lub adres internetowy. Adres ten jest zamieszczony w strukturze struct sockaddr s to deskryptor zwrócony przez socket() namelen to długość struktury struct sockaddr

37 Sockets ls –l mojegniazdo srwxr-xr-x 1 rudy users 0 Jan 21 16:22 mojegniazdo

38 Sockets Gniazdo typu przestrzeń UNIX #include int bind (sd, (struct sockaddr *) &addr, length); Gniazdo typu przestrzeń Internet #include int bind (sd, (struct sockaddr *) &addr, length); w przypadku gniazd typu przestrzeń UNIX użycie bind() powoduje utworzenie gniazda jako widocznego przez np. komendę ls zbioru; można użyc unlink() czy rm() aby gniazdo usunąć.

39 Stream sockets Użycie gniazda jest zwykle niesymetryczne. Jeden proces działa jako serwer, drugi jako klient. Serwer używa bind() aby przywiązać adres do gniazda. Następnie (dla gniazda SOCK_STREAM) serwer woła funkcję listen(int s, int backlog), której parametr backlog określa jak wiele jednocześnie usiłowań połączenia z gniazdem może być przyjętych do kolejki (nadmiarowe zostaną odrzucone). Parametr s to deskryptor zwrócony przez socket(). Proces-serwer blokuje się teraz, czeka aż pojawi się jakaś komunikacja na gnieździe.

40 Stream sockets Proces-klient inicjalizuje połączenie do gniazda utworzonego przez proces-serwer używając funkcji int connect(int s, struct sockaddr *name, int namelen) ; W przypadku przestrzeni-domeny UNIX: connect (sd, (struct sockaddr_un *)&server, length) ; W przypadku przestrzeni-domeny Internet: connect (sd, (struct sockaddr_in *)&server, length) ;

41 Stream sockets Teraz proces-serwer akceptuje połączenie, woła funkcje accept() która zwraca nowy deskryptor gniazda, na użytek tylko tego jednego połączenia. Proces-serwer może mieć jedocześnie wiecej niż jedno aktywne połączenie SOCK-STREAM. int accept(int s, struct sockaddr *addr, int *addrlen) addr i addrlen są wskaźnikami do obiektów modyfikowanych przezaccept(). Struktura wskazywana przez addr jest wypełniana informacjami o łączącym się procesie, tak jak jest to znane warstwie komunikacyjnej protokołu. *addrlen zwraca wielkość struktury na która wskazuje addr. Można podać addrlen równe NULL, wtedy nic nie jest wypełniane podczas wykonania accept().

42 Stream sockets Istnieje wiele funkcji które można wykorzystać do czytania i pisania po połączeniu się przez gniazdo typu SOCK_STREAM. write(), read(), send(), recv(). Można również używać np.. buforowanych instrukcji WE/WY, po użyciu fdopen. SOCK_STREAM zamyka się przez close().

43 Datagram sockets można używać np. send() oraz recv(). Natomiast nie używa się accept() oraz listen().

44 Program serwer1.c /* Wspolpracuje z klient1.c */ #include #define NSTRS 3 #define ADDRESS mojegniazdo" /* adres */

45 Program serwer1.c char *strs[NSTRS] = { SERWER to pierwszy wiersz.\n", SERWER to drugi wiersz.\n", SERWER to trzeci wiersz.\n" };

46 Program serwer1.c int main() { char c; FILE *fp; int fromlen; register int i, s, ns, len; struct sockaddr_un saun, fsaun; /* W UNIX space-domain */ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("server: socket"); exit(1); }

47 Program serwer1.c /* Stworz adres */ saun.sun_family = AF_UNIX; strcpy(saun.sun_path, ADDRESS); unlink(ADDRESS); /* dla pewności zniszcz gniazdo */

48 Program serwer1.c len = sizeof(saun.sun_family) + strlen(saun.sun_path); /* przywiazanie adresu */ if (bind(s,(struct sockaddr*) &saun, len) < 0) { perror("server: bind"); exit(1); }

49 Program serwer1.c /* nadsluchiwanie */ if (listen(s, 5) < 0) { perror("server: listen"); exit(1); } /* akceptowanie */ if ((ns = accept(s, (struct sockaddr*) &fsaun, &fromlen)) < 0) { perror("server: accept"); exit(1); }

50 Program serwer1.c /* użycie fdopen() */ fp = fdopen(ns, "r"); /* przeslanie kilku wierszy do klienta */ for (i = 0; i < NSTRS; i++) send(ns, strs[i], strlen(strs[i]), 0);

51 Program serwer1.c /* Teraz czytanie kilku wierszy od klienta */ for (i = 0; i < NSTRS; i++) { while ((c = fgetc(fp)) != EOF) { putchar(c); if (c == '\n') break; }

52 Program serwer1.c /* oczywiście można by czytać od klienta używając int recv(int s, void *buf, size_t len, int flags); np. recv(s, bufor, 10000,0) gdzie bufor[] to zdefiniowana dodatkowa macierz typu char patrz man 2 recv */ /* zakonczenie polaczenia */ close(s); exit(0); }

53 server1.c proponowane ćwiczenie: uruchomienie powyższego programu np. w tle, (utworzy się mojegniazdo) a następnie uruchomienie programu poniższego

54 Program klient1.c #include #define NSTRS 3 /* liczba wierszy przesyłanych */ #define ADDRESS mojegniazdo" /* adres typu UNIX */

55 Program klient1.c char *strs[NSTRS] = { To pierwszy wiersz od klienta.\n, To drugi wiersz od klienta.\n, To trzeci wiersz od klienta.\n };

56 Program klient1.c int main() { char c; FILE *fp; register int i, s, len; struct sockaddr_un saun; /* otworz gniazdo do pracy; typ UNIX */ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("client: socket"); exit(1); }

57 Program klient1.c /* utworz adres do którego się dolaczymy */ saun.sun_family = AF_UNIX; strcpy(saun.sun_path, ADDRESS); len = sizeof(saun.sun_family) + strlen(saun.sun_path); /* len = sizeof(saun) */

58 Program klient1.c if (connect(s, &saun, len) < 0) { perror("client: connect"); exit(1); } /* zamiast używać recv() do czytania, użyjemy getc(), wcześniej musimy użyć fdopen aby mieć FILE * fp */ fp = fdopen(s, "r");

59 Program klient1.c /* czytanie tego co przesyła serwer */ for (i = 0; i < NSTRS; i++) { while ((c = fgetc(fp)) != EOF) { putchar(c); if (c == '\n') break; }

60 Program klient1.c /* teraz przesylanie DO SERWERA */ for (i = 0; i < NSTRS; i++) send(s, strs[i], strlen(strs[i]), 0); /* zamykanie */ close(s); exit(0); }

61 socket poniższy przykład będzie dotyczył przesyłania przez gniazdo z jednego komputera na inny komputer. na pewnym komputerze proces utworzy gniazdo, nada mu ADRES i będzie czekał... p

62 Program serwer2.c #include #define NSTRS 3 /* ilosc wierszy */

63 Program serwer2.c main() { char c; FILE *fp; int fromlen; register int i, s, ns, len; struct sockaddr_in saun, fsaun;

64 Program serwer2.c /* utworzenie gniazda typ Internet */ if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("server: socket"); exit(1); }

65 Program serwer2.c /* utworzenie adresu; tu adres to adres TEGO KOMPUTERA */ saun.sin_family = AF_INET; saun.sin_port = htons( (uint16_t) ); /* numer portu */ saun.sin_addr.s_addr = htonl (INADDR_ANY);

66 Program serwer2.c /* przywiązanie adresu do gniazda */ if (bind(s,(struct sockaddr *) &saun, sizeof(saun)) < 0) { perror("server: bind"); exit(1); }

67 Program serwer2.c /* sluchanie na gnieździe (listen on socket) */ if (listen(s, 5) < 0) { perror("server: listen"); exit(1); } /* akceptowanie przychodzącego do gniazda połączenia */ if ((ns = accept(s, &fsaun, &fromlen)) < 0) { perror("server: accept"); exit(1); }

68 Program serwer2.c /* do czytania będzie wykorzystywane getc() zamiast recv() */ fp = fdopen(ns, "r"); for (i = 0; i < NSTRS; i++) { while ((c = fgetc(fp)) != EOF) { putchar(c); if (c == '\n') break; }

69 Program serwer2.c /* dalsze czytanie, nieco inaczej wykorzystywane */ /* for (i = 0; i < NSTRS; i++) */ for (;;) /* pętla nieskończona */ {ns = accept(s, &fsaun, &fromlen); fp = fdopen(ns, "r"); while ((c = fgetc(fp)) != EOF) { putchar(c); printf("%"); } printf("\n byl KONIEC PLIKU ! \n"); } close(s); exit(0); } /* koniec main */

70 htonl, htons, ntohl, ntohs konwertują wartości pomiędzy host order oraz network byte order #include uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);

71 htonl, htons, ntohl, ntohs Big endian machine: It assumes that the first byte it reads is the biggest Little endian machine: It assumes that the first byte it reads is the littlest. short int: Big endian machine 256 * byte 0 + byte 1 Little endian machine 256 * byte 1 + byte 0

72 htonl, htons, ntohl, ntohs duże systemy komputerowe mainframe IBM, HONYWELL stacje robocze – SUN, HP, także komputery z LINUXem, DEC Alpha, VAX, PDP

73 Program klient2.c #include #define NSTRS 3 /* no. of strings */

74 Program klient2.c int main() { char c; FILE *fp; int adres; register int i, s, len; struct sockaddr_in saun; /* utwórz gniazdo INTERNET space-domain */ if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("client: socket"); exit(1); }

75 Program klient2.c /* utworzenie adresu */ saun.sin_family = AF_INET; saun.sin_port = htons( (uint16_t) 10000); /* to numer portu */ /* saun.sin_addr.s_addr = htonl(INADDR_ANY); */ /* dla adresu IP a.b.c.d, np */ adres=149*pow(16,6) + 156*pow(16,4) + 2*pow(16,2)+ 32; saun.sin_addr.s_addr = htonl( adres ); /* dolaczenie do saun.sin_addr.s_addr = htonl( 0x959c0220); */

76 Program klient2.c /* teraz proba podlaczenia się do adresu; serwer w tej chwili nadsluchuje listen() */ if (connect(s, (struct sockaddr *) &saun, sizeof(saun)) < 0) { perror("client: connect"); exit(1); }

77 Program klient2.c /* nastepuje wyslanie kilku wierszy do serwera */ for (i = 0; i < NSTRS; i++) { send(s, strs[i], strlen(strs[i]), 0); sleep(1); } /* zakończenie */ close(s); exit(0); }

78 połączenie z wykorzystaniem SOCK_DGRAM w przykladach serwer2.c, klient2.c wystarczy zamienić SOCK_STREAM SOCK_DGRAM, oraz w serwer2.c usunąć listen() i accept()

79 Język C podsumowanie Struktura programu w języku C Zmienne, Stałe Operacje arytmetyczne Operatory logiczne Priorytety operatorów Instrukcje warunkowe (if, ?:, switch) Pętle (for, while, do-while, instrukcje break i continue) Macierze i łańcuchy znakowe (także macierze wielowymiarowe)

80 Język C podsumowanie /* Alokuje pamiec na macierz n*n */ double **matrixalloc(int n) { int i; double ** bufor; bufor = malloc(n*sizeof(double *)); for(i=0; i

81 Język C podsumowanie Funkcje, prototypy funkcji Struktury, unie Rzutowanie na typ Klasy pamięci zmiennych i funkcji Zasięg zmiennej, zasięg funkcji Wskaźniki, macierze, funkcje Dynamiczna alokacja pamięci (malloc,calloc, sizeof, free) Argumenty wiersza wywołania programu Operatory arytmetyczne, logiczne Operatory bitowe, pola bitowe

82 Język C podsumowanie Preprocesor języka C (makra) Funkcje wejścia/wyjścia(buforowane, niebuforowane, formatowane, bezformatowe) Typ enum Instrukcja typedef Kwalifikatory const, volatile Czytanie deklaracji obiektów w języku C Przykłady (sortowanie, kompresja, struktury danych, IPC itp.)

83 Język C podsumowanie....tego nie było... biblioteka ncurses libncurses.a web.cs.mun.ca/~rod/ncurses/ncurses.html

84 Język C podsumowanie javascript (operatory i pętle jak w C)

85 Język C podsumowanie PHP (operatory, pętle jak w C)

86 Język C podsumowanie C++ Sposób zapisywania deklaracji obiektów w C++ jest identyczny jak w języku C. W C++ są klasy i dziedziczenie, czego nie ma w C, ale np. struktury w C++ to z definicji klasa, w której przez domniemanie wszystkie składniki są publiczne. struktura w C jest od razu struktura w C++ różnica: struktura w C++ może mieć funkcje składowe !!

87 Internet

88

89


Pobierz ppt "Semafory Semafor w programowaniu jest abstrakcją o zastosowaniu zaczerpniętym z działalności kolei. Gdy zasobów jest na tyle mało, że trzeba ich użyciem."

Podobne prezentacje


Reklamy Google