Wątki. S. Samolej: Wątki, producent - konsument 1
|
|
- Kajetan Bednarek
- 7 lat temu
- Przeglądów:
Transkrypt
1 Wątki dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: oraz na materiałach opracowanych przez dr inż. Jędrzeja Ułasiewicza: jedrzej.ulasiewicz.staff.iiar.pwr.wroc.pl S. Samolej: Wątki, producent - konsument 1
2 Potrzeba wprowadzania wątków W pewnych przypadkach tworzenie programów złożonych z wielu ciężkich procesów uważane jest za mało wydajne. Oczekuje się możliwości tworzenia aplikacji współbieżnych, które w bardziej naturalny sposób współdzielą pamięć i zasoby. Niektóre systemy operacyjne nie dysponują tak szerokim zestawem mechanizmów programowania współbieżnego opartych na współpracy procesów jak Unix i udostępniają mechanizmy programowania współbieżnego tylko na bazie wątków. S. Samolej: Wątki, producent - konsument 2
3 Definicja wątku Sekwencja działań, która może wykonywać się równolegle z innymi sekwencjami działań w kontekście danego procesu (programu). Tworzenie wątku a instrukcja fork Po uruchomieniu funkcji fork tworzony jest osobny proces z własnym zestawem zmiennych (odziedziczonych po rodzicu) i własnym identyfikatorem proces (PID). Po utworzeniu nowego wątku w procesie, otrzymuje on nowy stos (zmienne lokalne) ale współdzieli z innymi zmienne globalne, deskryptory plików, funkcje przechwytujące sygnały i stan bieżącego katalogu i procesu. S. Samolej: Wątki, producent - konsument 3
4 Zalety stosowania wątków Mniejszy nakład obliczeniowy ze strony systemu operacyjnego Możliwość tworzenia aplikacji, które mają wiele wątków pracujących na wspólnych danych lub zasobach (serwer bazy danych, serwer WWW, przetwarzanie w tle tekstu, zapis stanu jednostek w grach strategicznych itp.) Możliwość wydzielenia w aplikacji osobnych wątków pobierających dane, wysyłających dane i przetwarzających dane. Przetwarzanie może się odbywać, gdy operacje odczytu/zapisu są zablokowane. Przełączanie pomiędzy wątkami wymaga znacznie mniejszego nakładu obliczeniowego od SO S. Samolej: Wątki, producent - konsument 4
5 Wady stosowania wątków Tworzenie programów wielowątkowych wymaga precyzyjnego projektowania, ponieważ łatwo nieprzewidywalne wyniki spowodowane dostępem do zmiennych w czasie i przestrzeni Utrudnione jest śledzenie takich programów Aplikacja wielowątkowa na jednoprocesorowym komputerze nie musi działać szybciej niż jej jednowątkowa wersja. S. Samolej: Wątki, producent - konsument 5
6 Uwagi do tworzenia aplikacji wielowątkowych Należy włączyć bibliotekę pthread do opcji konsolidacji Należy włączyć makro: _REENTRANT (fragmenty kodu typu re-entrant mogą być równocześnie wywoływane przez wiele wątków w programie i nie zaszkodzi to ich spójności) #include <pthread.h> int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); S. Samolej: Wątki, producent - konsument 6
7 #include <pthread.h> void pthread_exit(void *retval); Kończenie pracy wątku Atrybuty: retval identyfikator wątku (można się jeszcze do niego odwołać, choć wątek zakończył działanie) Uwaga: Jako parametr retval nie należy podawać zmiennych lokalnych. Oczekiwanie na zakończenie wątku #include <pthread.h> int pthread_join(pthread_t th, void **thread_return); Atrybuty: th identyfikator wątku, na który oczekujemy thread_return wskaźnik na wskaźnik pokazujący na wartość zwracaną przez wątek Funkcja zwraca: 0 sukces, lub kod błędu. S. Samolej: Wątki, producent - konsument 7
8 #include <string.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> void *thread_function(void *arg); char message[] = "Hello World"; Pierwszy program wielowątkowy int main() { int res; pthread_t a_thread; void *thread_result; res = pthread_create(&a_thread, NULL, thread_function, (void *)message); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); printf("waiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res!= 0) { perror("thread join failed"); exit(exit_failure); printf("thread joined, it returned %s\n", (char *) thread_result); printf("message is now %s\n", message); exit(exit_success); void *thread_function(void *arg) { printf("thread_function is running. Argument was %s\n", (char *)arg); sleep(3); strcpy(message, "Bye!"); pthread_exit("thank you for the CPU time"); $./thread1 Waiting for thread to finish... thread_function is running. Argument was Hello World Thread joined, it returned Thank you for the CPU time Message is now Bye! S. Samolej: Wątki, producent - konsument 8
9 Jak to działa? thread_function jest funkcją, która rozpocznie działanie w nowym wątku W funkcji powoływany jest nowy wątek, obsługiwany przez thead_function, wątek przyjmuje domyślne parametry (NULL), a do funkcji wykonującej jako parametr zostaje wysłana tablica message Program główny kontynuuje swoje obliczenia i oczekuje na zakończenie utworzonego wątku (pthread_join) Wątek potwierdza odebranie danych przez parametr wywołania funkcji, modyfikuje stan współdzielonej zmiennej i kończy swoje działanie (pthread_exit). Następuje zakończenie programu macierzystego. S. Samolej: Wątki, producent - konsument 9
10 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> void *thread_function(void *arg); int run_now = 1; Sprawdzenie, czy wątki się przełączają? int main() { int res; pthread_t a_thread; void *thread_result; int print_count1 = 0; res = pthread_create(&a_thread, NULL, thread_function, (void *)message); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); while(print_count1++ < ) { if (run_now == 1) { printf("1"); run_now = 2; printf("\nwaiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res!= 0) { perror("thread join failed"); exit(exit_failure); printf("thread joined\n"); exit(exit_success); void *thread_function(void *arg) { int print_count2 = 0; while(print_count2++ < ) { if (run_now == 2) { printf("2"); run_now = 1; sleep(3); $./thread Waiting for thread to finish... Thread joined S. Samolej: Wątki, producent - konsument 10
11 Problem aktywnego czekania Każdy z wątków aplikacji sprawdza stan zmiennej run_now. Jeśli przyjmuje ona zadaną wartość, program wypisuje tę wartość i zmienia na drugą z możliwych Oba wątki wykonują niekorzystne z punktu wydajności systemu aktywne czekanie i próbkowanie stanu zmiennej Większość mocy obliczeniowej procesora zużywana jest na sprawdzanie stanu zmiennej w każdym z wątków. S. Samolej: Wątki, producent - konsument 11
12 Definicja semafora Semafor S jest obiektem systemu operacyjnego z którym związany jest licznik L zasobu przyjmujący wartości nieujemne. Na semaforze zdefiniowane są atomowe operacje sem_init, sem_wait i sem_post. Operacja Oznaczenie Opis Inicjacja semafora S sem_init(s,n) Ustawienie licznika semafora S na początkową wartość N. Zajmowanie sem_wait(s) Gdy licznik L semafora S jest dodatni (L > 0) zmniejsz go o 1 (L = L 1). Gdy licznik L semafora S jest równy zero (L= 0) zablokuj proces bieżący. Sygnalizacja sem_post(s) Gdy istnieje jakiś proces oczekujący na semaforze S to odblokuj jeden z czekających procesów. Gdy brak procesów oczekujących na semaforze S zwiększ jego licznik L o 1 (L=L+1). S. Samolej: Wątki, producent - konsument 12
13 sem_wait(s) { if(licznik L sem. S dodatni) { L=L-1; else { Zawieś proces bieżący Algorytmy funkcji semafora sem_post (S) { if(istnieje proc. czekający na zasób) { Odblokuj jeden z tych procesów else { L=L+1; Uwaga! 1. Semafor nie jest liczbą całkowitą na której można wykonywać operacje arytmetyczne. 2. Operacje na semaforach są operacjami atomowymi. Niezmiennik semafora Aktualna wartość licznika L semafora S spełnia następujące warunki: 1. Jest nieujemna czyli: L >= 0 2. Jego wartość wynosi: L= N - Liczba_operacji(sem_wait) + Liczba_operacji(sem_post). (N jest wartością początkową licznika). Semafor binarny W semaforze binarnym wartość licznika przyjmuje tylko dwie wartości: 0 i 1. S. Samolej: Wątki, producent - konsument 13
14 Rodzaje semaforów Wyróżniamy następujące rodzaje semaforów: 1. Semafor ze zbiorem procesów oczekujących (ang. Blocked- set Semaphore) Nie jest określone który z oczekujących procesów ma być wznowiony. 2. Semafor z kolejką procesów oczekujących (ang. Blockedqueue Semaphore) Procesy oczekujące na semaforze umieszczone są w kolejce FIFO. Uwaga! Pierwszy typ semafora nie zapewnia spełnienia warunku zagłodzenia. S. Samolej: Wątki, producent - konsument 14
15 Podstawowe zastosowania semaforów - synchronizacja var consyn : semaphore (* init 0 *) process P1; (* waiting process *) statement X; sem_wait (consyn) statement Y; end P1; process P2; (* signalling proc *) statement A; sem_post (consyn) statement B; end P2; ` S. Samolej: Wątki, producent - konsument 15
16 Podstawowe zastosowania semaforów wzajemne wykluczanie dostępu var mutex : semaphore; (* initially 1 *) process P1; statement X sem_wait (mutex); statement Y sem_post (mutex); statement Z end P1; process P2; statement A; sem_wait (mutex); statement B; sem_post (mutex); statement C; end P2; S. Samolej: Wątki, producent - konsument 16
17 Semafory POSIX (1) Semafory nazwane identyfikowane są w procesach poprzez ich nazwę. Funkcja tworząca semafor: sem_t *sem_open(const char *name, int oflag, ); sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag, mode_t mode, int value); Parametry: name nazwa semafora w systemie, powinna zacząć się od znaku /. oflag jest ustawiana na O_CREAT gdy chcemy utworzyć semafor (jeśli dodamy flagę O_EXCL funkcja zwróci błąd, w przypadku, gdy taki semafor już istnieje). mode_t ustalenie kontroli dostępu do semafora value ustalenie wartości początkowej semafora. Funkcja zwraca uchwyt do semafora lub błąd SEM_FAILED z zapisaną odpowiednią wartością w zmiennej errno. Od tej chwili w programie dostęp do semafora odbywa się za pomocą tego uchwytu. Pojedyncze wywołanie tworzy semafor, inicjalizuje go i ustala zasady dostępu do niego. S. Samolej: Wątki, producent - konsument 17
18 Semafory POSIX (2) Funkcja inicjalizująca semafor: int sem_init(sem_t *sem, int pshared, unsigned int value); pshared : 0-semofor jest dzielony pomiędzy wątki, >0 może być dzielony pomiędzy procesy value: początkowa wartość semafora Funkcja opuszczająca semafor: Funkcja podnosząca semafor: Funkcja zamykająca dostęp do semafora: Funkcja usuwająca semafor z sytemu: int sem_wait(sem_t *sem); int sem_post(sem_t *sem); int sem_close(sem_t *sem); int sem_unlink(const char *name); Uwagi: Po zakończeniu korzystania z semafora należy zamknąć do niego dostęp wywołując funkcję sem_close(). Usunięcie semafora z sytemu odbywa się po wywołaniu funkcji sem_unlink(). Jeśli jakiś inny proces lub wątek mają dostęp do tego semafora, to wywołanie funkcji sem_unlink() nie da żadnego efektu. Funkcje dodatkowe: int sem_trywait(sem_t *sem); - przejęcie semafora, jeśli jest dostępny, lub zgłoszenie błędu i kontynuowanie wątku obliczeniowego. int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); /* struct timespec { time_t tv_sec; /* Seconds */ long tv_nsec; /* Nanoseconds [ ] */ ; */ - przejęcie semafora do wywołania jeśli jest dostępny lub oczekiwanie na przejęcie przez S. Samolej: Wątki, producent - konsument 18 określony czas.
19 Synchronizacja z zastosowaniem semaforów #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> void *thread_function(void *arg); sem_t bin_sem; #define WORK_SIZE 1024 char work_area[work_size]; int main() { int res; pthread_t a_thread; void *thread_result; res = sem_init(&bin_sem, 0, 0); if (res!= 0) { perror("semaphore initialization failed"); exit(exit_failure); res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); printf("input some text. Enter 'end' to finish\n"); while(strncmp("end", work_area, 3)!= 0) { fgets(work_area, WORK_SIZE, stdin); sem_post(&bin_sem); printf("\nwaiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res!= 0) { perror("thread join failed"); exit(exit_failure); printf("thread joined\n"); sem_destroy(&bin_sem); exit(exit_success); void *thread_function(void *arg) { sem_wait(&bin_sem); while(strncmp("end", work_area, 3)!= 0) { printf("you input %d characters\n", strlen(work_area) -1); sem_wait(&bin_sem); pthread_exit(null); S. Samolej: Wątki, producent - konsument 19
20 Wyjście programu $./thread3 Input some text. Enter end to finish The Wasp Factory You input 16 characters Iain Banks You input 10 characters end Waiting for thread to finish... Thread joined S. Samolej: Wątki, producent - konsument 20
21 Komentarz W programie rozwiązano problem synchronizacji z zastosowaniem semaforów Wartość początkowa semafora ustawiana jest na 0 Podstawowy wątek cyklicznie odbiera od użytkownika komunikaty tekstowe i zapisuje do bufora, a następnie zwalnia semafor (sem_post). Wątek potomny najpierw oczekuje na zwolnienie semafora (sem_wait), a potem cyklicznie analizuje zawartość bufora z danymi (długość tekstu) i oczekuje na ustawienie semafora (sem_wait). S. Samolej: Wątki, producent - konsument 21
22 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> void *thread_function(void *arg); sem_t bin_sem; #define WORK_SIZE 1024 char work_area[work_size]; int main() { int res; pthread_t a_thread; void *thread_result; res = sem_init(&bin_sem, 0, 0); if (res!= 0) { perror("semaphore initialization failed"); exit(exit_failure); res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); Zależności czasowe printf("input some text. Enter 'end' to finish\n"); while(strncmp("end", work_area, 3)!= 0) { if (strncmp(work_area, "FAST", 4) == 0) { sem_post(&bin_sem); strcpy(work_area, "Wheeee..."); else { fgets(work_area, WORK_SIZE, stdin); sem_post(&bin_sem); printf("\nwaiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res!= 0) { perror("thread join failed"); exit(exit_failure); printf("thread joined\n"); sem_destroy(&bin_sem); exit(exit_success); void *thread_function(void *arg) { sem_wait(&bin_sem); while(strncmp("end", work_area, 3)!= 0) { printf("you input %d characters\n", strlen(work_area) -1); sem_wait(&bin_sem); pthread_exit(null); S. Samolej: Wątki, producent - konsument 22
23 Wyjście programu $./thread4a Input some text. Enter end to finish Excession You input 9 characters FAST You input 7 characters You input 7 characters You input 7 characters end Waiting for thread to finish... Thread joined S. Samolej: Wątki, producent - konsument 23
24 Komentarz Kiedy użytkownik wprowadza słowo FAST na wejście programu to następuje zwolnienie semafora, Warunek zakończenia pętli while nie jest spełniony Następuje rozpoznanie, że użytkownik wprowadził wyraz FAST, ponowne zwolnienie semafora, a następnie wprowadzenie do współdzielonej zmiennej tekstu Wheeee Ponowny raz semafor zostaje zwolniony Warunek zakończenia pętli while nie jest spełniony Program oczekuje na wprowadzenie nowego tekstu na standardowym wejściu Zmiany zawartości współdzielonej zmiennej odbywają się tak szybko, że wątek obliczający długość tekstu gubi jedną ze zmian. Wątek macierzysty podczas wywoływania funkcji sem_post() zwiększa licznik. W konsekwencji wątek potomny, który wcześniej nie uzyskał dostępu do współdzielonej zmiennej trzykrotnie odblokowuje się na semaforze i wypisuje obliczoną długość tekstu. S. Samolej: Wątki, producent - konsument 24
25 Mutexy Wątki dzielą wspólny obszar danych. Stąd współbieżny dostęp do danych może naruszyć ich integralność. Należy zapewnić synchronizację dostępu do wspólnych danych. W bibliotece pthreads do zapewnienia wyłączności dostępu do danych stosuje się mechanizm muteksu (ang. mutex). Nazwa ta pochodzi od słów Mutual exclusion czyli wzajemne wykluczanie. S. Samolej: Wątki, producent - konsument 25
26 Funkcje do obsługi mutexów #include <pthread.h> //Inicjalizacja: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); // Zamknięcie dostępu do sekcji krytycznej: int pthread_mutex_lock(pthread_mutex_t *mutex)); // Otwarcie dostępu do sekcji krytycznej: int pthread_mutex_unlock(pthread_mutex_t *mutex); // Zniszczenie mutex a int pthread_mutex_destroy(pthread_mutex_t *mutex); Uwagi: Funkcje korzystają ze wcześniej zadeklarowanego obiektu typu: pthread_mutex_t Funkcja dodatkowa: // - przejęcie mutex a, jeśli jest dostępny, lub zgłoszenie błędu i kontynuowanie wątku obliczeniowego. int pthread_mutex_trylock(pthread_mutex_t *mutex); // - przejęcie mutex a, jeśli jest dostępny lub oczekiwanie przez abs_timeout na jego przejęcie int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout); S. Samolej: Wątki, producent - konsument 26
27 Przykład ochrona współdzielonych danych z zastosowaniem mutex a #define _REENTRANT #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <string.h> void *thread_function(void *arg); pthread_mutex_t work_mutex; #define WORK_SIZE 1024 char work_area[work_size]; char texts[3][50]={ "First text\n", "Second text\n", "Third text\n"; int main() { int res; pthread_t a_thread; void *thread_result; int i=0,j=0; res = pthread_mutex_init(&work_mutex, NULL); if (res!= 0) { perror("mutex initialization failed"); exit(exit_failure); res = pthread_create(&a_thread, NULL,thread_function, NULL); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); while(j<15) { pthread_mutex_lock(&work_mutex); strcpy(work_area,texts[i]); pthread_mutex_unlock(&work_mutex); i = (i + 1) % 3; j++; sleep(2); printf("bye\n"); res = pthread_join(a_thread, &thread_result); if (res!= 0) { perror("thread join failed"); exit(exit_failure); pthread_mutex_destroy(&work_mutex); exit(exit_success); void *thread_function(void *arg) { int i=0; while(i<20) { pthread_mutex_lock(&work_mutex); printf("current text: %s",work_area); pthread_mutex_unlock(&work_mutex); sleep(1); i++; pthread_exit(0); S. Samolej: Wątki, producent - konsument 27
28 Current text: First text Current text: First text Current text: Second text Current text: Second text Current text: Third text Current text: Third text Current text: First text Current text: First text Current text: Second text Current text: Second text Current text: Third text Current text: Third text Current text: First text Current text: First text Current text: Second text Current text: Second text Current text: Third text Current text: Third text Current text: First text Current text: First text Bye Wyjście programu S. Samolej: Wątki, producent - konsument 28
29 Jak to działa? W obszarze zmiennych globalnych zadeklarowano nową zmienną work_mutex W głównej funkcji programu zainicjalizowano mutex Powołano nowy wątek który: próbuje zamknąć mutex (jeśli jest zamknięty, to oczekuje na jego otwarcie), wypisuje stan współdzielonej zmiennej work_area otwiera mutex W wątku macierzystym : następuje próba zamknięcia mutex a do współdzielonego obszaru pamięci następuje przypisanie kolejnej wartości z tablicy napisów texts następuje otwarcie semafora Uwaga: Program pokazuje zasadę wymiany informacji pomiędzy wątkami na zasadzie wzajemnego wykluczania. Tylko jeden z puli wątków może wykonywać sekcję krytyczną - zestaw indtrukcji ochroninych przez mutex. S. Samolej: Wątki, producent - konsument 29
30 Argumenty wątków (wybrane) #include <pthread.h> // Inicjalizacja możliwości ustalania atrybutów wątków int pthread_attr_init(pthread_attr_t *attr); // Ustalenie sposobu zakończenia wątku: int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); // Sprawdzenie, w jaki sposób wątek będzie kończony int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); // Ustalenie sposobu szeregowania wątku: int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); // Sprawdzenie w jaki sposób wątek będzie szeregowany: int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy); // //... // S. Samolej: Wątki, producent - konsument 30
31 Kończenie wątku bez oczekiwania na wspólne zakończenie #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> void *thread_function(void *arg); char message[] = "Hello World"; int thread_finished = 0; int main() { int res; pthread_t a_thread; void *thread_result; pthread_attr_t thread_attr; res = pthread_attr_init(&thread_attr); if (res!= 0) { perror("attribute creation failed"); exit(exit_failure); res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); if (res!= 0) { perror("setting detached attribute failed"); exit(exit_failure); res = pthread_create(&a_thread, &thread_attr, thread_function, (void *)message); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); (void)pthread_attr_destroy(&thread_attr); while(!thread_finished) { printf("waiting for thread to say it's finished...\n"); sleep(1); printf("other thread finished, bye!\n"); exit(exit_success); void *thread_function(void *arg) { printf("thread_function is running. Argument was %s\n", (char *)arg); sleep(4); printf("second thread setting finished flag, and exiting now\n"); thread_finished = 1; pthread_exit(null); S. Samolej: Wątki, producent - konsument 31
32 Wyjście programu $./thread5 Waiting for thread to say it s finished... thread_function is running. Argument was Hello World Waiting for thread to say it s finished... Waiting for thread to say it s finished... Waiting for thread to say it s finished... Second thread setting finished flag, and exiting now Other thread finished, bye! S. Samolej: Wątki, producent - konsument 32
33 Komentarz W programie została zainicjalizowana zmienna typu pthread_attr_t Przed uruchomieniem wątku wykonana została funkcja pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); funkcja zmodyfikowała zmienną thread_attr w taki sposób, że, jeśli zostanie utworzony wątek z tą zmienną jako atrybut, to po jego zakończeniu wątek macierzysty nie będzie oczekiwał na wątek potomny S. Samolej: Wątki, producent - konsument 33
34 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #define NUM_THREADS 6 void *thread_function(void *arg); int main() { int res; pthread_t a_thread[num_threads]; void *thread_result; int lots_of_threads; for(lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) { Wielo-wielowątkowa aplikacja res = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void *)&lots_of_threads); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); sleep(1); printf("waiting for threads to finish...\n"); for(lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0; lots_of_threads--) { res = pthread_join(a_thread[lots_of_threads], &thread_result); if (res == 0) { printf("picked up a thread\n"); else { perror("pthread_join failed"); printf("all done\n"); exit(exit_success); void *thread_function(void *arg) { int my_number = *(int *)arg; int rand_num; printf("thread_function is running. Argument was %d\n", my_number); rand_num=1+(int)(9.0*rand()/(rand_max+1.0)); sleep(rand_num); printf("bye from %d\n", my_number); pthread_exit(null); S. Samolej: Wątki, producent - konsument 34
35 Wyjście programu $./thread8 thread_function is running. Argument was 0 thread_function is running. Argument was 1 thread_function is running. Argument was 2 thread_function is running. Argument was 3 thread_function is running. Argument was 4 Bye from 1 thread_function is running. Argument was 5 Waiting for threads to finish... Bye from 5 Picked up a thread Bye from 0 Bye from 2 Bye from 3 Bye from 4 Picked up a thread Picked up a thread Picked up a thread Picked up a thread Picked up a thread All done S. Samolej: Wątki, producent - konsument 35
36 Jak to działa? W pętli następuje wygenerowanie NUM_THREADS wątków. Każdy z wątków ustala losowy czas, kiedy ma zakończyć swoje obliczenia Główny program zbiera zakończone wątki (uwaga: wątki kończą się w różnej kolejności, ale zbieranie odbywa się po kolei zgodnie z numerami wątków zapisanymi w tablicy a_thread) S. Samolej: Wątki, producent - konsument 36
37 Interesujące zjawisko Interesujące wyniki programu otrzymuje się, gdy zrezygnuje się w nim z wywołań funkcji sleep: okazuje się, że kilka wątków startuje z tą samą wartością przekazywaną im jako parametr wywołania problematyczną linią programu jest: for(lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) {res = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void *)&lots_of_threads); do wątku przekazywane jest wskazanie na zmienną, pomimo, że zmienna zmienia się w pętli, komórka pamięci, w której powinien być przechowywany jej stan nie jest aktualizowana Rozwiązanie problemu: res = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void *)lots_of_threads); Modyfikacji musi też ulec fragment funkcji obsługującej wątek: void *thread_function(void *arg) { int my_number = (int)arg; S. Samolej: Wątki, producent - konsument 37
38 Producenci i konsumenci (1) W systemie działa P>0 procesów, które produkują pewne dane oraz K>0 procesów, które odbierają dane od producentów. Między producentami a konsumentami może znajdować się bufor o pojemności B, którego zadaniem jest równoważenie chwilowych różnic w czasie działania procesów. Procesy produkujące dane będziemy nazywać producentami, a procesy odbierające dane --- konsumentami. Zadanie polega na synchronizacji pracy producentów i konsumentów, tak aby: 1. Konsument oczekiwał na pobranie danych w sytuacji, gdy bufor jest pusty. Gdybyśmy pozwolili konsumentowi odbierać dane z bufora zawsze, to w sytuacji, gdy nikt jeszcze nic w buforze nie zapisał, odebrana wartość byłaby bezsensowna. 2. Producent umieszczając dane w buforze nie nadpisywał danych już zapisanych, a jeszcze nie odebranych przez żadnego konsumenta. Wymaga to wstrzymania producenta w sytuacji, gdy w buforze nie ma wolnych miejsc. 3. Jeśli wielu konsumentów oczekuje, aż w buforze pojawią się jakieś dane oraz ciągle są produkowane nowe dane, to każdy oczekujący konsument w końcu coś z bufora pobierze. Nie zdarzy się tak, że pewien konsument czeka w nieskończoność na pobranie danych, jeśli tylko ciągle napływają one do bufora. 4. Jeśli wielu producentów oczekuje, aż w buforze będzie wolne miejsce, a konsumenci ciągle coś z bufora pobierają, to każdy oczekujący producent będzie mógł coś włożyć do bufora. Nie zdarzy się tak, że pewien producent czeka w nieskończoność, jeśli tylko ciągle z bufora coś jest pobierane. S. Samolej: Wątki, producent - konsument 38
39 Producenci i konsumenci (2) Rozpatruje się różne warianty tego problemu: 1. Bufor może być nieskończony. 2. Bufor cykliczny może mieć ograniczoną pojemność. 3. Może w ogóle nie być bufora. 4. Może być wielu producentów lub jeden. 5. Może być wielu konsumentów lub jeden. 6. Dane mogą być produkowane i konsumowane po kilka jednostek na raz. 7. Dane muszą być odczytywane w kolejności ich zapisu lub nie. Problem producentów i konsumentów jest abstrakcją wielu sytuacji występujących w systemach komputerowych, na przykład zapis danych do bufora klawiatury przez sterownik klawiatury i ich odczyt przez system operacyjny. S. Samolej: Wątki, producent - konsument 39
40 Rozwiązanie problemu producent-konsument (pamięć dzielona) S. Samolej: Wątki, producent - konsument 40
41 Szkic rozwiązania z zastosowaniem semaforów (1) #define BufSize 8 // Bufor ma 8 elementów RecType Buffer[BufSize]; // Buf. na elementy semaphore Mutex; // Ochrona bufora semaphore Puste; // Wolne bufory semaphore Pelne; // Zajete bufory int count; // Wskaźnik bufora producent(void) { RecType x; do {... produkcja rekordu x; // Czekaj na wolny bufor sem_wait(puste); sem_wait(mutex); // Umieść element x w buforze Buffer[count] = x; count++; sem_post(mutex); // Pojawił się nowy element sem_post(pelne); while(1); konsument(void) { RecType x; do { // Czekaj na element sem_wait(pelne); sem_wait(mutex); // Pobierz element x z bufora count--; x = Buffer[count]; sem_post(mutex); // Zwolnij miejsce w buforze sem_post(puste); konsumpcja rekordu x;... while(1); S. Samolej: Wątki, producent - konsument 41
42 Szkic rozwiązania z zastosowaniem semaforów (1) main(void) { count = 0; sem_init(puste,bufsize); sem_init(pelne,0); sem_init(mutex,1); pthread_create(,producent,..);.. pthread_create(,konsument,..);.. // Inicjacja semafora Puste // Inicjacja semafora Pelne // Inicjacja semafora Mutex // Start K wątków producenta // Start L wątków konsumenta S. Samolej: Wątki, producent - konsument 42
43 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <pthread.h> #include <semaphore.h> #include <assert.h> #include <sys/stat.h> #include <sys/file.h> #define BSIZE 4 // Buffer size #define LSIZE 80 // LIne length typedef struct { // Shared data char buf[bsize][lsize]; int head; int tail; int cnt; bufor_t; bufor_t shared_memory; bufor_t* shared_stuff; #define NUM_PROD 3 pthread_t a_prod_thread[num_prod]; #define NUM_CONS 2 pthread_t a_cons_thread[num_cons]; Rozwiązanie pamięć dzielona (1) void *prod_thread_function(void *arg); void *cons_thread_function(void *arg); void *thread_result; sem_t *mutex, *empty, *full; int main(){ int res; int i; shared_stuff = &shared_memory; shared_stuff->head=0; shared_stuff->tail=0; shared_stuff->cnt=0; mutex = sem_open("mutex",o_creat,s_irwxu,1); empty = sem_open("empty",o_creat,s_irwxu,bsize); full = sem_open("full",o_creat,s_irwxu,0); printf("producers are created...\n"); for(i=0;i<num_prod;i++) { res = pthread_create(&(a_prod_thread[i]), NULL, prod_thread_function, (void *)i); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); printf("consumers are created...\n"); for(i=0;i<num_cons;i++) { res = pthread_create(&(a_cons_thread[i]), NULL, cons_thread_function, (void *)i); if (res!= 0) { perror("thread creation failed"); exit(exit_failure); S. Samolej: Wątki, producent - konsument 43
44 Rozwiązanie pamięć dzielona (2) printf("waiting for producer threads to finish...\n"); for(i = NUM_PROD - 1; i >= 0; i--) { res = pthread_join(a_prod_thread[i], &thread_result); if (res == 0) { printf("picked up a thread\n"); else { perror("pthread_join failed"); printf("waiting for consumer threads to finish...\n"); for(i = NUM_CONS - 1; i >= 0; i--) { res = pthread_join(a_prod_thread[i], &thread_result); if (res == 0) { printf("picked up a thread\n"); else { perror("pthread_join failed"); printf("all done\n"); exit(exit_success); void *prod_thread_function(void *arg) { int my_number = (int)arg; printf("producer %d is running\n",my_number); sleep(1); while(1){ static int j=0; sem_wait(empty); sem_wait(mutex); printf("producer %d - cnt: %d head: %d tail: %d\n", my_number, shared_stuff->cnt, shared_stuff->head,shared_stuff->tail); sprintf(shared_stuff->buf[shared_stuff->head], "Message %d from producer %d",j++,my_number); shared_stuff-> cnt ++; shared_stuff->head=(shared_stuff->head +1)%BSIZE; sem_post(mutex); sem_post(full); sleep(8); printf("bye from producer %d\n", my_number); pthread_exit(null); S. Samolej: Wątki, producent - konsument 44
45 Rozwiązanie pamięć dzielona (3) void *cons_thread_function(void *arg) { int my_number = (int)arg; printf("consumer %d is running\n",my_number); sleep(2); while(1) { sem_wait(full); sem_wait(mutex); printf("consumer %d - cnt: %d data received: %s\n", my_number, shared_stuff->cnt, shared_stuff->buf[shared_stuff->tail]); shared_stuff-> cnt --; shared_stuff->tail = (shared_stuff->tail +1) % BSIZE; sem_post(mutex); sem_post(empty); sleep(1); printf("bye from Consumer %d\n", my_number); pthread_exit(null); S. Samolej: Wątki, producent - konsument 45
46 Dyskusja Medium komunikacyjnym jest kolejka zrealizowana we współdzielonym obszarze pamięci Zalety: Mniejsze ograniczenia na rozmiar przesyłanych danych Wady: Konieczność samodzielnego zarządzania prawidłowym dostępem do danych Bardziej złożony kod Takie rozwiązanie zmniejsza ograniczenie ze względu na pojemność bufora do wymiany danych. Warto stosować takie rozwiązanie, gdy pomiędzy producentem, a konsumentem przesyłane są większe porcje danych/komunikaty S. Samolej: Wątki, producent - konsument 46
47 Producent-konsument kolejki (1) #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <mqueue.h> #include <sys/stat.h> #include <sys/wait.h> struct message { char mtext[128]; ; void producer(int prod_no, mqd_t qid){ int j= 0, r; struct message mes; while(1){ sprintf(mes.mtext,"message %d from producer %d",j++,prod_no); r = mq_send(qid, mes.mtext, strlen(mes.mtext) + 1, 1); if (r == -1) { perror("mq_send"); break; sleep(3); void consumer(int cons_no, mqd_t qid){ u_int pri; struct message msg; ssize_t len; while(1){ len = mq_receive(qid, (char *) &msg, sizeof(msg), &pri); if (len == -1) { perror("mq_receive"); break; printf("consumer %d, data received: %s\n", cons_no, msg.mtext); S. Samolej: Wątki, producent - konsument 47
48 Producent-konsument kolejki (2) int main(int argc, char *argv[]) { // Allow up to 10 messages before blocking. // Message size is 128 bytes (see above). struct mq_attr mattr = {.mq_maxmsg = 10,.mq_msgsize = sizeof(struct message) ; mqd_t mqid = mq_open("/myq", O_CREAT O_RDWR, S_IREAD S_IWRITE, &mattr); if (mqid == (mqd_t) -1) { perror("mq_open"); exit(1); // Fork a producer process, we'll be the consumer. pid_t pid = fork(); if (pid == 0) { producer(0,mqid); mq_close(mqid); exit(0); else { consumer(0,mqid); mq_close(mqid); int status; wait(&status); mq_unlink("/myq"); return 0; -- S. Samolej: Wątki, producent - konsument 48
49 Dyskusja Jako medium komunikacyjne zastosowano kolejkę Zalety: Prostota Automatyczna synchronizacja i wzajemne wykluczanie w dostępie do współdzielonego kanału komunikacyjnego System operacyjny sam zarządza dostępem do współdzielonego zasobu Wady: Ograniczoność pojemności kolejki W skrajnym wypadku nie będzie możliwe przesłanie danych, lub będzie możliwe przesłanie tylko pojedynczej struktury danych Warto stosować takie rozwiązanie, gdy pomiędzy producentem, a konsumentem przesyłane są niewielkie porcje danych/komunikaty S. Samolej: Wątki, producent - konsument 49
Wątki. S. Samolej: Wątki 1
Wątki dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/ oraz na materiałach
10. Synchronizacja użycia zasobów, Semafory Problem producenta i konsumenta
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 10. użycia zasobów, Semafory 10.1 Problem producenta i konsumenta Zagadnienie kontroli użycia jednostek zasobu W systemie istnieje pula N jednostek
Problem producentakonsumenta
Problem producentakonsumenta dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/
10. Synchronizacja użycia zasobów, Semafory
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 10. użycia zasobów, Semafory 10.1 Problem producenta i konsumenta Zagadnienie kontroli użycia jednostek zasobu W systemie istnieje pula N jednostek
Temat zajęć: Tworzenie i obsługa wątków.
Temat zajęć: Tworzenie i obsługa wątków. Czas realizacji zajęć: 180 min. Zakres materiału, jaki zostanie zrealizowany podczas zajęć: Tworzenie wątków, przekazywanie parametrów do funkcji wątków i pobieranie
Problemy czytelników i pisarzy oraz 5 ucztujących filozofów
Problemy czytelników i pisarzy oraz 5 dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/
w odróżnieniu od procesów współdzielą przestrzeń adresową mogą komunikować się za pomocą zmiennych globalnych
mechanizmy posix Wątki w odróżnieniu od procesów współdzielą przestrzeń adresową należą do tego samego użytkownika są tańsze od procesów: wystarczy pamiętać tylko wartości rejestrów, nie trzeba czyścić
10. Synchronizacja użycia zasobów, Semafory
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 10. użycia zasobów, Semafory 10.1 Problem producenta i konsumenta Zagadnienie kontroli użycia jednostek zasobu W systemie istnieje pula N jednostek
1. Procesy i współbieżność
1. Procesy i współbieżność Opracował: Sławomir Samolej Politechnika Rzeszowska, Katedra Informatyki i Automatyki, Rzeszów, 2013. 1.1. Wprowadzenie Proces to przestrzeń adresowa i pojedynczy wątek sterujący,
10. Synchronizacja użycia zasobów, Semafory
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 10. użycia zasobów, Semafory 10.1 Problem producenta i konsumenta Zagadnienie kontroli użycia jednostek zasobu W systemie istnieje pula N jednostek
Gdy kilka procesów czyta a przynajmniej jeden dokonuje zapisu wynik odczytu zależeć może od sposobu realizacji przeplotu.
Komputery i Systemy Równoległe Jędrzej Ułasiewicz 1 9. Wzajemne wykluczanie 9.1 Przeplot i współużywalność zasobów Wyróżniamy dwa rodzaje zasobów: 1. Zasoby współużywalne - mogą być wykorzystane przez
Semafory, pamięć dzielona i kolejki komunikatów
Semafory, pamięć dzielona i kolejki komunikatów dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/
Kolejki komunikatów POSIX
Jędrzej Ułasiewicz IIAiR Politechnika Wrocławska 1 Kolejki komunikatów POSIX 1 Wstęp Kolejka komunikatów Q posiada następujące własności: - Posiada określoną pojemność N komunikatów (długość bufora komunikatów).
1. Kolejki komunikatów POSIX
Jędrzej Ułasiewicz IIAiR Politechnika Wrocławska 1 1. Kolejki komunikatów POSIX 1.1 Podstawowe własności Kolejki FIFO maja następujące wady: Komunikaty pozbawione struktury Nie można testować stanu kolejki
Rys. 9-1 Procesy P1 i P2 komunikuję się poprzez wspólny obszar. pamięci.
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 9. Komunikacja przez pamięć dzieloną Metoda komunikacji przez wspólną pamięć może być użyta gdy procesy wykonywane są na maszynie jednoprocesorowej
1. Uruchom poniższy program tworzący pojedynczy wątek:
9 Wątki 1. Uruchom poniższy program tworzący pojedynczy wątek: #include #include #include void* worker(void* info) int i; for(i=0; i
Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.
Przykład: $ ls more Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi. Tworzenie łącza #include int pipe(int filedes[2]); Przykład: int
Problemy czytelników i pisarzy oraz 5 ucztujących filozofów
Problemy czytelników i pisarzy oraz 5 dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/
Programowanie współbieżne Wykład 10 Synchronizacja dostępu do współdzielonych zasobów. Iwona Kochańska
Programowanie współbieżne Wykład 10 Synchronizacja dostępu do współdzielonych zasobów Iwona Kochańska Mechanizm synchronizacji wątków/procesów Wykorzystanie semaforów zapobiega niedozwolonemu wykonaniu
13. Kolejki komunikatów POSIX
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 13. POSIX 13.1 Wstęp (mailboxy, bufory) są bardzo popularnym mechanizmem komunikacji międzyprocesowej. Występują w prawie każdym systemie operacyjnym.
Procesy i wątki. Krzysztof Banaś Obliczenia równoległe 1
Procesy i wątki Krzysztof Banaś Obliczenia równoległe 1 Procesy i wątki Proces: ciąg rozkazów (wątek główny) i ewentualnie inne wątki stos (wątku głównego) przestrzeń adresowa dodatkowe elementy tworzące
Pamięć dzielona i kolejki komunikatów
Pamięć dzielona i kolejki komunikatów dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/
1. Kolejki komunikatów POSIX
Jędrzej Ułasiewicz IIAiR Politechnika Wrocławska 1 1. Kolejki komunikatów POSIX 1.1 Podstawowe własności Kolejki FIFO maja następujące wady: Komunikaty pozbawione struktury Nie można testować stanu kolejki
Programowanie Współbieżne
Programowanie Współbieżne Pthread http://www.unix.org/version2/whatsnew/threadsref.html Oraz strony podręcznika systemowego man 1 Wątki W tradycyjnym modelu w systemie Unix, jeżeli proces wymaga, by część
Programowanie równoległe i rozproszone. Monitory i zmienne warunku. Krzysztof Banaś Programowanie równoległe i rozproszone 1
Programowanie równoległe i rozproszone Monitory i zmienne warunku Krzysztof Banaś Programowanie równoległe i rozproszone 1 Problemy współbieżności Problem producentów i konsumentów: jedna grupa procesów
SYSTEMY CZASU RZECZYWISTEGO - VxWorks
WZAJEMNE WYKLUCZANIE Wiele metod. Np. wyłączanie przerwań: funkcja() //... Int blokada = intlock(); // Obszar krytyczny, któremu nie możemy przerwać intunlock(blokada); wyłączanie wywłaszczania: funkcja()
METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02
METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE Wykład 02 NAJPROSTSZY PROGRAM /* (Prawie) najprostszy przykład programu w C */ /*==================*/ /* Między tymi znaczkami można pisać, co się
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO LABORATORIUM Temat: THREADS Mariusz Rudnicki 2016 1. Przygotowanie platformy i środowiska IDE. Przed uruchomieniem własnego kodu zwiększ priorytet procesu qconn
Przetwarzanie wielowątkowe przetwarzanie współbieżne. Krzysztof Banaś Obliczenia równoległe 1
Przetwarzanie wielowątkowe przetwarzanie współbieżne Krzysztof Banaś Obliczenia równoległe 1 Problemy współbieżności wyścig (race condition) synchronizacja realizowana sprzętowo (np. komputery macierzowe)
J. Ułasiewicz Programowanie aplikacji współbieżnych 1
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 9. Komunikacja przez pamięć dzieloną Metoda komunikacji przez wspólną pamięć może być użyta gdy procesy wykonywane są na maszynie jednoprocesorowej
1. Utwórz blok pamięci współdzielonej korzystając z poniższego kodu:
6 Pamięć współdzielona 6.1 Dostęp do pamięci współdzielonej 1. Utwórz blok pamięci współdzielonej korzystając z poniższego kodu: #include #include #include #include
4. Procesy pojęcia podstawowe
4. Procesy pojęcia podstawowe 4.1 Czym jest proces? Proces jest czymś innym niż program. Program jest zapisem algorytmu wraz ze strukturami danych na których algorytm ten operuje. Algorytm zapisany bywa
J. Ułasiewicz Programowanie aplikacji współbieżnych 1
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 9. Komunikacja przez pamięć dzieloną Pamięć wirtualna Procesy nie adresują bezpośrednio pamięci fizycznej. Zamiast tego system operacyjny przydziela
Dzisiejszy wykład. Klasa string. wersja prosta wersja ze zliczaniem odwołań. Wyjątki Specyfikator volatile Semafory
Dzisiejszy wykład Klasa string wersja prosta wersja ze zliczaniem odwołań Wyjątki Specyfikator volatile Semafory 1 Klasa string Przetwarzanie tekstów jest powszechną dziedziną zastosowań komputerów W języku
Programowanie równoległe i rozproszone. W1. Wielowątkowość. Krzysztof Banaś Programowanie równoległe i rozproszone 1
Programowanie równoległe i rozproszone W1. Wielowątkowość Krzysztof Banaś Programowanie równoległe i rozproszone 1 Problemy współbieżności wyścig (race condition) synchronizacja realizowana sprzętowo (np.
Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach
Laboratorium Systemów Operacyjnych Ćwiczenie 4. Operacje na plikach Wykonanie operacji wymaga wskazania pliku, na którym operacja ma zostać wykonana. Plik w systemie LINUX identyfikowany jest przez nazwę,
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO LABORATORIUM Temat: QNX Neutrino Interrupts Mariusz Rudnicki 2016 Wstęp W QNX Neutrino wszystkie przerwania sprzętowe przechwytywane są przez jądro systemu. Obsługę
Wykład 3. Procesy i wątki. Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB
Wykład 3 Procesy i wątki Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB Pojęcie procesu Program = plik wykonywalny na dysku Proces = uruchomiony i wykonywany program w pamięci
Procesy. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 9 października 2011
Procesy Systemy Operacyjne 2 laboratorium Mateusz Hołenko 9 października 2011 Plan zajęć 1 Procesy w systemie Linux proces procesy macierzyste i potomne procesy zombie i sieroty 2 Funkcje systemowe pobieranie
4. Procesy pojęcia podstawowe
4. Procesy pojęcia podstawowe 4.1 Czym jest proces? Proces jest czymś innym niż program. Program jest zapisem algorytmu wraz ze strukturami danych na których algorytm ten operuje. Algorytm zapisany bywa
procesy odrębne dzielone
procesy odrębne Unikatowy PID (2-32000) Zmienne Zbiory deskryptorów plików Przestrzeń stosu (lokalne zmienne, wywołania funkcji) Środowisko Licznik rozkazów dzielone Kod programu brak możliwości zapisu
Wielozadaniowość w systemie Microsoft Windows
Wielozadaniowość w systemie Microsoft Windows mgr inż. Tomasz Jaworski tjaworski@kis.p.lodz.pl http://tjaworski.kis.p.lodz.pl/ Idea wielozadaniowości Proces główny Wątki Algorytm szeregowania ustala kolejność
Biblioteka standardowa - operacje wejścia/wyjścia
Biblioteka standardowa - operacje wejścia/wyjścia Przemysław Gawroński D-10, p. 234 Wykład 6 15 stycznia 2019 (Wykład 6) Biblioteka standardowa - operacje wejścia/wyjścia 15 stycznia 2019 1 / 14 Outline
IPC: Kolejki komunikatów
IPC: Kolejki komunikatów Systemy Operacyjne 2 laboratorium Mateusz Hołenko 7 listopada 2011 Plan zajęć 1 Mechanizmy IPC kolejki komunikatów pamięć współdzielona semafory 2 Kolejki komunikatów kolejka komunikat
Plan wykładu. Obliczenia równoległe w zagadnieniach inżynierskich. Wykład 1 p. Wzajemne wykluczanie. Procesy współbieżne
Plan wykładu Obliczenia równoległe w zagadnieniach inżynierskich Wykład 1 Podstawowe pojęcia i model programowania Sposoby realizacji watków w systemach operacyjnych Tworzenie watów i zarzadzanie nimi
Mariusz Rudnicki PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.4
Mariusz Rudnicki mariusz.rudnicki@eti.pg.gda.pl PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO CZ.4 Synchronizacja wątków Omawiane zagadnienia Czym jest synchronizacja wątków? W jakim celu stosuje się mechanizmy
Jędrzej Ułasiewicz Programownie aplikacji współbieżnych str. 1. Wątki
Jędrzej Ułasiewicz Programownie aplikacji współbieżnych str. 1 1 Informacje wstępne...2 2 Rodzaje wątków...7 poziomu jądra...7 poziomu użytkownika...8 Rozwiązania mieszane...8 3 Biblioteka pthreads...12
Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011
Obsługa plików Systemy Operacyjne 2 laboratorium Mateusz Hołenko 25 września 2011 Plan zajęć 1 Pliki w systemie Linux i-węzły deskryptory plików 2 Operacje na plikach otwieranie i zamykanie zapis i odczyt
SYSTEMY OPERACYJNE WYKLAD 6 - procesy
Wrocław 2007 SYSTEMY OPERACYJNE WYKLAD 6 - procesy Paweł Skrobanek C-3, pok. 323 e-mail: pawel.skrobanek@pwr.wroc.pl www.equus.wroc.pl/studia.html 1 Zasoby: PROCES wykonujący się program ; instancja programu
Struktury. Przykład W8_1
Struktury Struktury pozwalają na grupowanie zmiennych różnych typów pod wspólną nazwą. To istotnie ułatwia organizacje danych, które okazują się w jednym miejscu kodu programu. To jest bardzo ważne dla
Mariusz Rudnicki PROGRAMOWANIE WSPÓŁBIEŻNE I SYSTEMY CZASU RZECZYWISTEGO CZ.4
Mariusz Rudnicki mariusz.rudnicki@eti.pg.gda.pl PROGRAMOWANIE WSPÓŁBIEŻNE I SYSTEMY CZASU RZECZYWISTEGO CZ.4 Synchronizacja wątków Omawiane zagadnienia Czym jest synchronizacja wątków? W jakim celu stosuje
Wykład 4. Synchronizacja procesów (i wątków) cześć I. Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB
Wykład 4 Synchronizacja procesów (i wątków) cześć I Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB Potrzeba synchronizacji Procesy wykonują się współbieżnie. Jeżeli w 100% są
Poniższe funkcje opisane są w 2 i 3 części pomocy systemowej.
Procesy Proces (zwany też zadaniem) jest jednostką aktywną, kontrolowaną przez system operacyjny i związaną z wykonywanym programem. Proces ma przydzielone zasoby typu pamięć (segment kodu, segment danych,
Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17
Wskaźniki Przemysław Gawroński D-10, p. 234 Wykład 2 8 marca 2019 (Wykład 2) Wskaźniki 8 marca 2019 1 / 17 Outline 1 Wskaźniki 2 Tablice a wskaźniki 3 Dynamiczna alokacja pamięci (Wykład 2) Wskaźniki 8
Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego
Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego 1 /24 Pisanie pojedynczych znaków z klawiatury do pliku #include void main(void) { FILE *fptr; // wkaznik do pliku, tzw. uchwyt
Gniazda BSD. komunikacja bezpołączeniowa
Gniazda BSD komunikacja bezpołączeniowa Użycie gniazd w transmisji bezpołączeniowej socket() socket() bind() bind() STOP! recv() żądanie send() send() odpowiedź recv() STOP! recvfrom() #include
Argumenty wywołania programu, operacje na plikach
Temat zajęć: Argumenty wywołania programu, operacje na plikach Autor: mgr inż. Sławomir Samolej Zagadnienie 1. (Zmienne statyczne) W języku C można decydować o sposobie przechowywania zmiennych. Decydują
9. Problem wzajemnego wykluczania i sekcji krytycznej
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 9. Problem wzajemnego wykluczania i sekcji krytycznej 9.1 Przeplot i współużywalność zasobów Wyróżniamy dwa rodzaje zasobów: 1. Zasoby współużywalne
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO
PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO LABORATORIUM Temat: THREADS SYNCHRONIZATION METHODS Mariusz Rudnicki 2016 1. Wstęp W systemach wielowątkowych wspólne zasoby procesu takie, jak: pamięć: kod programu;
Systemy operacyjne III
Systemy operacyjne III WYKŁAD 3 Jan Kazimirski 1 Współbieżność 2 Współbieżność Wielozadaniowość - zarządzanie wieloma procesami w ramach jednego CPU Wieloprocesorowość - zarządzanie wieloma zadaniami w
Tworzenie programów równoległych cd. Krzysztof Banaś Obliczenia równoległe 1
Tworzenie programów równoległych cd. Krzysztof Banaś Obliczenia równoległe 1 Metodologia programowania równoległego Przykłady podziałów zadania na podzadania: Podział ze względu na funkcje (functional
Podstawy programowania współbieżnego. 1. Wprowadzenie. 2. Podstawowe pojęcia
Podstawy programowania współbieżnego Opracowanie: Sławomir Samolej, Tomasz Krzeszowski Politechnika Rzeszowska, Katedra Informatyki i Automatyki, Rzeszów, 2010 1. Wprowadzenie Programowanie współbieżne
J. Ułasiewicz Programowanie aplikacji współbieżnych 1
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 9. Komunikacja przez pamięć dzieloną Pamięć wirtualna Procesy nie adresują bezpośrednio pamięci fizycznej. Zamiast tego system operacyjny przydziela
Programowanie współbieżne Wykład 2. Iwona Kochańska
Programowanie współbieżne Wykład 2 Iwona Kochańska Miary skalowalności algorytmu równoległego Przyspieszenie Stały rozmiar danych N T(1) - czas obliczeń dla najlepszego algorytmu sekwencyjnego T(p) - czas
Semafor nie jest mechanizmem strukturalnym. Aplikacje pisane z użyciem semaforów są podatne na błędy. Np. brak operacji sem_post blokuje aplikację.
J. Ułasiewicz Programowanie aplikacji współbieżnych 1 11 Semafor nie jest mechanizmem strukturalnym. Aplikacje pisane z użyciem semaforów są podatne na błędy. Np. brak operacji sem_post blokuje aplikację.
Tworzenie wątków. #include <pthread.h> pthread_t thread;
Wątki Wątek (ang, thread) jest to niezależna sekwencja zdarzeń w obrębie procesu. Podczas wykonywania procesu równolegle i niezależnie od siebie może być wykonywanych wiele wątków. Każdy wątek jest wykonywany
JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6
JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 6 1 SPECYFIKATOR static Specyfikator static: Specyfikator ten powoduje, że zmienna lokalna definiowana w obrębie danej funkcji nie jest niszczona
Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.
Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych. 1. Rodzaje pamięci używanej w programach Pamięć komputera, dostępna dla programu,
Pobieranie argumentów wiersza polecenia
Pobieranie argumentów wiersza polecenia 2. Argumenty wiersza polecenia Lista argumentów Lista argumentów zawiera cały wiersz poleceń, łącznie z nazwą programu i wszystkimi dostarczonymi argumentami. Przykłady:
Aplikacja Sieciowa wątki po stronie klienta
Aplikacja Sieciowa wątki po stronie klienta Na ostatnich zajęciach zajmowaliśmy się komunikacją pomiędzy klientem a serwerem. Wynikiem naszej pracy był program klienta, który za pomocą serwera mógł się
1. Timery i zdarzenia
Sygnały 1 1. Timery i zdarzenia 1.1 Funkcje i programowanie timerów Jedną z najczęściej spotykanych funkcji systemu jest generowanie zdarzeń które w ustalonym czasie uruchomić mają określone akcje systemu.
Funkcje zawarte w bibliotece < io.h >
PLIKOWE OPERACJE WEJŚCIA - WYJŚCIA Język C/C++ nie ma wbudowanych żadnych instrukcji umożliwiających wykonywanie operacji wejścia-wyjścia! Służą do tego funkcje biblioteczne. Funkcje zawarte w bibliotece
Sygnały. 7. Sygnały (2005/2006)
Sygnały Sygnał jest to informacja dla procesu, że wystąpiło jakieś zdarzenie. Sygnały mogą być wysyłane: z procesu do innego procesu (grupy procesów) z procesu do siebie samego z jądra do procesu Sygnały
Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1 Pętle Pętla jest konstrukcją sterującą stosowaną w celu wielokrotnego wykonania tego samego zestawu instrukcji jednokrotne
Funkcja (podprogram) void
Funkcje Co to jest funkcja? Budowa funkcji Deklaracja, definicja i wywołanie funkcji Przykłady funkcji definiowanych przez programistę Przekazywanie argumentów do funkcji Tablica jako argument funkcji
Podstawy programowania skrót z wykładów:
Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace
Zasady programowania Dokumentacja
Marcin Kędzierski gr. 14 Zasady programowania Dokumentacja Wstęp 1) Temat: Przeszukiwanie pliku za pomocą drzewa. 2) Założenia projektu: a) Program ma pobierać dane z pliku wskazanego przez użytkownika
Podstawy programowania komputerów
Podstawy programowania komputerów Wykład 14: Programowanie współbieżne w C Definicja programowania współbieżnego Programowanie współbieżne jest tworzeniem programów, których wykonanie powoduje uruchomienie
Łącza nienazwane(potoki)
8. Łącza nienazwane(potoki) Łącze (potok, ang. pipe) jest to urządzenie komunikacyjne pozwalające na przesyłanie informacji w jedną stronę. Jeden proces wysyła dane do łącza za pomocą funkcji write, zaś
Pliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików:
Pliki W celu wykonania jakiejkolwiek operacji na istniejącym pliku, plik ten musi zostać otwarty, natomiast jeśli plik jeszcze nie istnieje, to musi zostać utworzony. Plik może zostać otwarty w trybie:
WYKŁAD 10. Zmienne o złożonej budowie Statyczne i dynamiczne struktury danych: lista, kolejka, stos, drzewo. Programy: c5_1.c, c5_2, c5_3, c5_4, c5_5
WYKŁAD 10 Zmienne o złożonej budowie Statyczne i dynamiczne struktury danych: lista, kolejka, stos, drzewo Programy: c5_1.c, c5_2, c5_3, c5_4, c5_5 Tomasz Zieliński ZMIENNE O ZŁOŻONEJ BUDOWIE (1) Zmienne
3. Identyfikacja. SKŁADNIA #include <sys/socket.h> int getpeername(int socket, struct sockaddr *addr, int *addrlen);
3.1. Określanie adresu połączonego hosta 3. #include int getpeername(int socket, struct sockaddr *addr, int *addrlen); Funkcja getpeername dostarcza adresu drugiej strony połączenia. Parametry:
Dynamiczny przydział pamięci w języku C. Dynamiczne struktury danych. dr inż. Jarosław Forenc. Metoda 1 (wektor N M-elementowy)
Rok akademicki 2012/2013, Wykład nr 2 2/25 Plan wykładu nr 2 Informatyka 2 Politechnika Białostocka - Wydział Elektryczny Elektrotechnika, semestr III, studia niestacjonarne I stopnia Rok akademicki 2012/2013
Procesy i wątki. Blok kontrolny procesu. Proces. Proces - elementy. Stan procesu
Proces Procesy i wątki Proces jest wykonywanym programem. Wykonanie procesu musi przebiegać w sposób sekwencyjny ( w dowolnej chwili na zamówienie naszego procesu może być wykonany co najwyżej jeden rozkaz
4.2 Sposób korzystania z l acza
4.2 Sposób korzystania z l acza 31 Opis programu: Program procesu potomnego (linie 16 19) jest taki sam, jak w przyk ladzie na listingu 3. W procesie macierzystym nastepuje z kolei przekierowanie standardowego
Obsługa plików Procesy
Obsługa plików Procesy Systemy Operacyjne 2 laboratorium Mateusz Hołenko 15 października 2011 Plan zajęć 1 Obsługa plików 1 Pliki w systemie Linux i-węzły deskryptory plików 2 Operacje na plikach 3 Operacje
Systemy Operacyjne 2: Wątki pthreads. dr inż. Arkadiusz Chrobot
Systemy Operacyjne 2: Wątki pthreads dr inż. Arkadiusz Chrobot 18 kwietnia 2013 1. Wprowadzenie Wątki podobnie jak procesy umożliwiają współbieżną realizację czynności w wykonywanym programie. Domyślnie
Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja
Funkcje zawarte w bibliotece < io.h >
PLIKOWE OPERACJE WEJŚCIA - WYJŚCIA Język C/C++ nie ma wbudowanych żadnych instrukcji umożliwiających wykonywanie operacji wejścia-wyjścia! Służą do tego funkcje biblioteczne. Funkcje zawarte w bibliotece
Procesy. S. Samolej: Procesy
Procesy dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/ oraz Na materiałach
Programowanie wielowątkowe. Jarosław Kuchta
Programowanie wielowątkowe Jarosław Kuchta Procesy i wątki w systemie Windows Windows jest systemem wielowątkowym. Każdy proces ma przynajmniej jeden wątek, chociaż może mieć wiele wątków. Start programu,
Programowanie Proceduralne
Programowanie Proceduralne Struktury Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 10 Co dziś będzie: Definiowanie struktury Deklarowanie zmiennych bȩda cych strukturami
Struktura programu. Projekty złożone składają się zwykłe z różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem.
Struktura programu Projekty złożone składają się zwykłe z różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem. W ostatnich latach najbardziej używanym stylem oprogramowania
2 Przygotował: mgr inż. Maciej Lasota
Laboratorium nr 2 1/7 Język C Instrukcja laboratoryjna Temat: Wprowadzenie do języka C 2 Przygotował: mgr inż. Maciej Lasota 1) Wprowadzenie do języka C. Język C jest językiem programowania ogólnego zastosowania
Systemy operacyjne III
Systemy operacyjne III WYKŁAD 2 Jan Kazimirski 1 Procesy w systemie operacyjnym 2 Proces Współczesne SO w większości są systemami wielozadaniowymi. W tym samym czasie SO obsługuje pewną liczbę zadań procesów
Stałe i zmienne znakowe. Stała znakowa: znak
Stałe i zmienne znakowe. Stała znakowa: znak Na przykład: a, 1, 0 c Każdy znak jest reprezentowany w pamięci przez swój kod. Kody alfanumerycznych znaków ASCII to liczby z przedziału [32, 127]. Liczby
I.Wojnicki, Tech.Inter.
Igor Wojnicki (AGH, KA) 13 maja 2012 1 / 26 Hypertext Preprocessor Igor Wojnicki Katedra Automatyki Akademia Górniczo-Hutnicza w Krakowie 13 maja 2012 $Id: php1.tex,v 1.1 2011/11/19 19:14:25 wojnicki Exp
Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.
Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni Wykład 6 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411b Plan wykładu Operacje wejścia-wyjścia Dostęp do plików Struktury
Ingerencja w kod systemu operacyjnego (przerwania) Programowanie na niskim poziomie (instrukcje specjalne) Trudności implementacyjne (alg.
Wady mechanizmów niskopoziomowych Ingerencja w kod systemu operacyjnego (przerwania) Programowanie na niskim poziomie (instrukcje specjalne) Trudności implementacyjne (alg. Dekkera zależny od liczby synchronizowanych
Wstęp do programowania 2
Wstęp do programowania 2 wykład 10 Zadania Agata Półrola Wydział Matematyki UŁ 2005/2006 http://www.math.uni.lodz.pl/~polrola Współbieżność dotychczasowe programy wykonywały akcje sekwencyjnie Ada umożliwia