88
Programowanie Wspólbieżne Tomasz Surmacz [email protected] Niniejsza publikacja stanowi materialy do wykladu prowadzonego na Politechnice Wroclawskiej i ma charakter autorski. Rozpowszechnianie dozwolone wylącznie do użytku prywatnego wśród studentów uczęszczających na wyklad, jako materialy uzupelniające. c Tomasz Surmacz, Wroclaw, 22 listopada 2010

Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz [email protected] Niniejsza publikacja stanowi materiały

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

Programowanie Współbieżne

Tomasz Surmacz

[email protected]

Niniejsza publikacja stanowi materiały do wykładu prowadzonego na Politechnice Wrocławskiej i ma charakter autorski. Rozpowszechnianie

dozwolone wyłącznie do użytku prywatnego wśród studentów uczęszczających na wykład, jako materiały uzupełniające.

c©Tomasz Surmacz, Wrocław, 22 listopada 2010

Page 2: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

Zagadnienia wstępne

Zagadnienia wstępne

• Semestr 9: 30h laboratorium (013/c3) w cyklu 4h co 2 tygodnie

• Semestr 9: 16h wykładu:

czwartki 11:15-12:45, 23/c3 przez 8 tygodni

Konsultacje i formy kontaktu

• Konsultacje: wtorki 13-15, środy 13-15

• e-mail: [email protected], Subject: PW lub INE5242

• WWW: http://pleple.ict.pwr.wroc.pl/pw/

• Poczta studencka: http://student.pwr.wroc.pl/

Literatura

• Stevens, W. Richard – Programowanie zastosowań sieciowych w systemie UNIX

• Bach, Maurice J. – Budowa systemu operacyjnego UNIX

• Silberschatz, Abraham – Podstawy systemów operacyjnych

• Ben-Ari, M. – Podstawy programowania współbieżnego

Programowanie Współbieżne, INE 5242, 2010/2011 2

Page 3: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

Zagadnienia wstępne

Zebr. zakl.

17:00

19:00

17:00

15:00

13:00

11:00

9:00

PN WT SR CZ PT

15:00

13:00

11:00

19:00

17:00

15:00

13:00

11:00

17:00

15:00

13:00

11:0011:00

PN

BUS P

013/c3

9:00

17:00

19:00 19:00

17:00

9:00

konsultacje12:45-14:00 105/c3 13:00

19:00

BUS P17:00-19:00

013/c3

BUS P013/c3

konsultacje17-19 105/c3

SSO/L

18:00-20:35 127P/c3

15:00

SSO/W

15:00-17:45 23/c3

P.Wsp.lab

17.05-20.05 013/c3

P.Wsp.lab

14:15-17:00 013/c3

11:15-13:00

P.Wsp/W23/c3

P.Wsp.lab

17.05-20.05013/c3

P.Wsp.lab

17.05-20.05013/c3

9:009:00

BUS W

23/c3

Kalendarz akademicki (tyg. nieparzyste itp.): http://www.pwr.wroc.pl/14884.xml

Programowanie Współbieżne, INE 5242, 2010/2011 3

Page 4: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

Program kursu

Program kursu

• Podstawy systemu UNIX

• System plików i prawa dostępu

• Wejście i wyjście w systemie UNIX

• Procesy, kontekst procesu, sterowanie procesami

• Sygnały, grupy procesów

• Strumienie pipe i FIFO

• Kolejki komunikatów

• Semafory, problemy współbieżności

• Pamięć wirtualna, stronicowanie i segmentacja

• Wątki

Programowanie Współbieżne, INE 5242, 2010/2011 4

Page 5: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX System UNIX

Podstawy systemu UNIX

System UNIX

Początki – 1970: Ken Thompson, Dennis Ritchie (Bell Laboratories) na maszynie PDP-7, następnie PDP-11/20

• 1973 – pierwsza wersja z jądrem napisanym w C

• 1979 – BSD Unix (University of California, Berkeley)

• 1983 – Unix System V

• 1990 – Unix System V Release 4

• XINU (XINU Is Not UNIX) – system „edukacyjny”

• 1987 – Minix (A. Tanenbaum)

• 1991 – Linux 0.02 (Linus Torvalds)

Brian Kernighan – język C, powstał specjalnie w celu zapewnienia przenośności pisanego oprogramowania

Programowanie Współbieżne, INE 5242, 2010/2011 1-1

Page 6: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX System UNIX

Podstawowe cechy systemu

• system wieloużytkownikowy

• system wielozadaniowy (wiele procesów)

• podział czasu

• wywłaszczanie procesów

• podsystem plików

• zarządzanie pamięcią

• biblioteki systemowe

• wszystkie urządzenia dostępne przez pliki specjalne

3 podstawowe wersje: (1988)

• Version 7 (wczesny odłam komercyjny)

• Berkeley – BSD 4.1 vs. BSD 4.2 (BSD4.4) (wersja „akademicka”)

• System V – SysV Rel.3, SysV Rel.2 (SVR4) (wersja komercyjna)

Obecnie: Pochodne BSD lub SysV (lub obu)

Programowanie Współbieżne, INE 5242, 2010/2011 1-2

Page 7: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX System UNIX

Podstawowe różnice:

• parametry wykonania komend (np. ps -ef lub ps -aux)

• różne koncepcje dostępu do terminali (strumienie w SysV)

• inna obsługa przerwań systemowych (sygnałów)

• inne umiejscowienie standardowych programów

Standardy:

• ANSI C

• POSIX (Portable Operating System Interface)

• X/Open

• „Jedną z najwspanialszych zalet związanych ze standaryzacją jest to, że obowiązujących standardów jest takwiele, że zawsze znajdzie się taki, który nam odpowiada.”

Licencje:

• Systemy komercyjne: SysV, SCO, Solaris, HPUX, OSF, ...

• FreeBSD, Linux

• FSF & GNU

• Licencja GPL

Programowanie Współbieżne, INE 5242, 2010/2011 1-3

Page 8: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Fundamentalne cechy wszystkich systemów UNIX

Fundamentalne cechy wszystkich systemów UNIX

• Mechanizm ochrony bezpieczeństwa rozgraniczający użytkowników i administratora systemu

• Podział na pracę w trybie użytkownika i w trybie jądra systemu(wspomagany mechanizmami ochrony procesora)

• W trybie jądra wykonują się wszystkie funkcje systemowe

• Przejście do trybu jądra realizowane przez przerwania programowe

• System sterowany zdarzeniami (a nie „polling”) – aplikacje nie tracą czasu, oddając go innym procesom, a samesą usypiane, biernie czekając na wystąpienie oczekiwanego zdarzenia

• Wszystkie1 urządzenia, mechanizmy komunikacji wewnętrznej i sieciowej itp. dostępne są przez pliki i deskryp-tory plików

• System plików umożliwiający kontrolę dostępu do plików i blokowanie prawa do zapisu pomiędzy procesami.

• Pamięć wirtualna i system plików stosują te same mechanizmy – pełna integracja.

• Prosty i spójny interfejs zapewniany przez system operacyjny – około 300 funkcji systemowych (MS-Windows– kilkadziesiąt tysięcy)

1prawie

Programowanie Współbieżne, INE 5242, 2010/2011 1-4

Page 9: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX System plików

System plików

• Separatorem ścieżki jest znak „/”

• Katalog / to „korzeń” (root) systemuplików

• Wszystkie katalogi/dyski są podłączonejako gałęzie drzewa katalogów – zarównolokalne, jak i zdalne.

• Różne rodzaje systemów plików: UFS,SysV, minix, ext2, MSDOS, NFS

• Komendy związane z plikami: ls, cd,pwd, mkdir, rmdir, cat, mv, cp, rm,mount, umount, df, du, quota

• Pliki: /etc/fstab, /etc/mntab,/etc/exports

• Dziurawe pliki (sparse files – man tar,man rsync)

/

usr bin

local

lib

etcbin

lib

var

spool

bin

log

/dev/dsk/c0t0d1s1

/dev/dsk/c1t2d0s4home

user1user2

cyber:/export/home

/dev/dsk/c0t0d1s0

dev

Programowanie Współbieżne, INE 5242, 2010/2011 1-5

Page 10: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Zarządzanie pamięcią

Zarządzanie pamięcią

• Pamięć fizyczna systemu podzielona jest na strony

• Rozmiar strony – z reguły 4-8-32 kB

• Dostęp do stron pamięci realizowany jest przez tablicę deskryptorów pamięci, z pomocą sprzętowych układówMMU

• Pamięć wirtualna

– Swoboda adresowania

– Możliwość zaadresowania większego obszaru pamięci niż dostępny

– Stronicowanie pamięci/plik wymiany – dokonywane automatycznie

Podział pamięci w systemie UNIX

• Pamięć jądra systemu

• Bufory dyskowe

• Plik(i) wymiany (swap)

• Pamięć procesów użytkowników

– Kod programu (TEXT)

– Dane

– Stos

– Stos wywołań systemowych

Programowanie Współbieżne, INE 5242, 2010/2011 1-6

Page 11: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Biblioteki

Biblioteki

• Język C określa konstrukcje sterujące wykonaniem programu

• Funkcje nie są częścią języka C, lecz bibliotek systemowych lub programów – nawet najbardziej podstawowe,jak printf ()

• Funkcje systemowe znajdują się w bibliotekach dynamicznych, takich jak libc.so

• Biblioteki statyczne (np. /usr/lib/libc.a)

– dołączane w całości lub częściowo do kodu kompilowanego programu, w trakcie kompilacji

– programy linkowane statycznie są większe, lecz nie wymagają działającego linkera ld

• Biblioteki dynamiczne (np. /usr/lib/libsocket.so.2 )

– dołączane dynamicznie do kodu programu w trakcie jego uruchamiania

– zajmują region pamięci współdzielony z innymi procesami

– mniejsze zapotrzebowanie na pamięć

– mniejsze programy

– dynamiczny linker – programy ld i ldd

• Zmienna środowiskowa LD LIBRARY PATH

Programowanie Współbieżne, INE 5242, 2010/2011 1-7

Page 12: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Biblioteki

Podstawowe biblioteki systemowe:

• libc.so – standardowe funkcje wejścia/wyjścia, zarządzania pamięcią, itp.

• libm.so – funkcje matematyczne

• ld.so – linker dynamiczny

• libsocket.so – funkcje sieciowe (SysV)

• libnsl.so – „name server library” – tłumaczenie nazw komputerów na adresy

• libX11.so – funkcje systemu okienkowego X11

Narzędzia przydatne do tworzenia/badania bibliotek dynamicznych

• ldd

• nm, ar, ranlib

• objdump, readelf

Programowanie Współbieżne, INE 5242, 2010/2011 1-8

Page 13: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Użytkownicy

Użytkownicy

• System wielozadaniowy (multitasking)

• System wieloużytkownikowy (multiuser)

• Konieczność ochrony użytkowników przed sobą nawzajem

Atrybuty użytkownika – /etc/passwd :

root:x:0:1:Super-User:/root:/sbin/shts:x:103:10:Tomasz Surmacz:/home/ts:/usr/local/bin/tcshnobody:x:60001:60001:Nobody:/:

• Nazwa użytkownika

• Identyfikator (uid)

• Grupa (nazwa i identyfikator – gid)

• Komentarz (pole „GECOS” – imię/nazwisko, nr telefonu, itp.)

• Hasło dostępu – obecnie przeniesione do /etc/shadow

• Katalog domowy

• Interpreter poleceń (shell)

Programowanie Współbieżne, INE 5242, 2010/2011 1-9

Page 14: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Użytkownicy

Dla jądra systemu istotne są:

• uid procesu

• gid procesu

• prawa dostępu do pliku

• uprawnienia specjalne (uid==0)

Polecenia operujące na uid/gid:

• newgrp, su, login, id

Programowanie Współbieżne, INE 5242, 2010/2011 1-10

Page 15: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Prawa dostępu

Prawa dostępu

• Każdy plik w systemie ma swojego właściciela i właściciela grupowego

• Każdy plik opisany jest przez 3 grupy praw dostępu:

– dla właściciela (user)

– dla grupy (group)

– dla pozostałych użytkowników (other)

• Podstawowe prawa dostępu to

– (r)ead – odczyt

– (w)rite – pisanie

– e(x)ecute – wykonanie

drwxr-x--x 3

ogu

pozostali

grupa

własciciel

111101001 7 5 1

typ (katalog/plik/...)

root wheel

liczba dowiazan

Programowanie Współbieżne, INE 5242, 2010/2011 1-11

Page 16: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Prawa dostępu

Przykładowa zawartość katalogu domowego:

drwxr-x--x 44 ts users 2048 Feb 27 16:39 .drwxr-xr-x 47 ts users 3072 Feb 28 00:28 ..-rw------- 1 ts users 3476 May 25 2007 .cshrc-rw-r--r-- 1 ts users 16 Jun 28 2007 .forwarddrwx------ 2 ts mail 1024 Feb 27 03:44 Maildrwxr-xr-x 3 ts users 1024 Jun 2 2007 News-rw-r--r-- 1 ts wheel 4029 Feb 27 03:13 back.tar.gzdrwxr-xr-x 3 ts users 1024 Dec 1 14:31 hgttgdrwxr-xr-x 3 ts users 1024 Feb 27 03:44 ssodrwxr-xr-x 3 ts users 1024 Feb 27 03:19 src

Komendy pozwalające zmieniać prawa dostępu:

• chmod, chgrp

• chown (tylko użytkownik root!)

• umask

Programowanie Współbieżne, INE 5242, 2010/2011 1-12

Page 17: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Prawa dostępu

System plików UFS

• Sztywny podział na tablicęi-węzłów i bloki dyskowe

• I-węzeł numer 1 jest zawszekatalogiem głównym systemuplików

• I-węzeł zawiera prawa dostępu,liczbę dowiązań, daty (mtime,ctime, atime) i wskaźnik na numerbloku zawierającego plik

• Katalog jest plikiem specjalnym,zawierającym nazwy plikówi odpowiadające im numeryi-węzłów

• Tablica i-węzłów w rzeczywistościzajmuje około 0.5-2% pojemnościdysku

• Plik znika z dysku dopiero gdyliczba dowiązań zmaleje do 0

• df -k, df -i

/

1 . 1 .. 2 tmp

blok 23450

70 usr11 home 3 lib95 var

ala ma kota. ala ma kota. ala ma kota ala ma kota. ala ma kota. ala ma kota. ala

blok 39834

81 398340644 83 2125.09.2003

f

3 23450 d0755 0 013.10.2003

2 33220 d1777 0 010.10.2003

1 23450 d0755 0 013.09.2003

2 . 1 ..81 kot-ali

blok 33220

93 plik

Programowanie Współbieżne, INE 5242, 2010/2011 1-13

Page 18: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Prawa dostępu

Bity specjalne:

• -rwsr-xr-x – set-user-id

• -rwxr-sr-x – set-group-id

• -rw------T – sticky bit

• drwxr-sr-x – set-group-id

• drwxrwxrwt – sticky bit

• prw-rw-rw- – strumień (named pipe)

• srw-rw-rw- – gniazdo w domenie UNIX (UNIX-domain socket)

• brw-rw---- – urządzenie blokowe (block device)

• crw-rw---- – urządzenie znakowe (character device)

• lrwxrwxrwx – dowiązanie symboliczne (symbolic link)

Programowanie Współbieżne, INE 5242, 2010/2011 1-14

Page 19: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Wejście/wyjście

Wejście/wyjście

• standardowe wejście – stdin

• standardowe wyjście – stdout

• wyjście błędów – stderr

• strumień pipe

• przekierowanie we/wy: < > << >> | >& |&

grep cat -n sort -t: +1

/etc/passwd

tee abc

abc

grep :0: < /etc/passwd | cat -n | tee abc | sort -t: 1+

• system plików

• katalogi, podkatalogi, pliki

Programowanie Współbieżne, INE 5242, 2010/2011 1-15

Page 20: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

1. Podstawy systemu UNIX Środowisko pracy i środowisko programistyczne

Środowisko pracy i środowisko programistyczne

Interpreter poleceń – shell

• /bin/csh

• /bin/sh

• /sbin/sh

• bash

• tcsh

• Inne (zsh, ksh, emacs ;-))

Edytory tekstu

• vi

• emacs

• jed

• joe

Kompilatory

• cc

• gcc

• g++

• Program make wywołujący odpowiednie kompilatory i linker

• Linkowanie – ld lub gcc

• Pliki nagłówkowe: /usr/include, /usr/local/include

• Biblioteki: /usr/lib, /usr/local/lib

Uruchamianie programów

• Debugger systemowy adb (debugowanie i zmiana parametrówjądra działającego systemu)

• Debugger GNU gdb

• Ścieżka wykonania – katalog . (kropka)

Programowanie Współbieżne, INE 5242, 2010/2011 1-16

Page 21: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy

Procesy

• tworzone funkcją fork()

• unikalny pid

• przodek (rodzic)—potomek (dziecko)

• grupa procesów i przewodnik grupy

• przełączanie procesów/przełączaniekontekstu

• tablica procesów

• priorytety

• nice

Stany procesów:

t�ry� b

� u� zy� t

�k.�

t�ry� b

� j

�a� d

�ra� .�

u� s�´p io ny� g� o t�o w� y�

Programowanie Współbieżne, INE 5242, 2010/2011 2-1

Page 22: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Kontekst procesu

Kontekst procesu

• Każdy proces posiada własne segmenty kodu, danych i stosu.

• Jądro systemu, poprzez system obsługi pamięci wirtualnej, w chwili wykonywania procesu ma dostęp do jednegosegmentu kodu, jednego segmentu danych i jednego(∗) segmentu stosu.

• Tablica procesów zawiera wskaźniki do zapamiętanych kontekstów poszczególnych procesów – zawierającychich prywatne mapy odwzorowujące wszystkie trzy segmenty programu na segmenty pamięci fizycznej.

CPU

1

2

3

4

5

RAM

CPU

1

2

3

4

5

RAMproces 1

proces 2

proces 1

proces 2

kod

dane

stos

kod

dane

stos

kod

dane

stos

kod

dane

stos

kod

dane

stos

kod

dane

stos

• Przełączenie kontekstu polega na zapamiętaniu aktualnego stanu procesu (odwzorowanie segmentów pamięci,stan procesora) w jego obszarze kontekstu, po czym wczytaniu do procesora kontekstu innego procesu.

Programowanie Współbieżne, INE 5242, 2010/2011 2-2

Page 23: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Sterowanie procesami z powłoki użytkownika

Sterowanie procesami z powłoki użytkownika

• Każdy proces zwraca wartość: 0 – ok, >0 – błąd

• Separator komend: znak ; lub & lub znak nowej linii

• Uruchamianie w tle: proces &

• Łączenie procesów strumieniem: proces1 | proces2

• Warunkowe wykonanie drugiego procesu:

– jeśli pierwszy zakończył się poprawnie: proces1 && proces2

– jeśli pierwszy zakończył się błędem: proces1 || proces2

• Przekierowanie wyjścia błędów:

– csh: proces >& plik oraz proces1 |& proces2

– sh: proces > plik 2>&1

• Zatrzymanie procesu: stop %nazwa, Klawisz Ctrl-Z, kill -STOP, kill -SUSP

• Zabicie procesu lub wysłanie sygnału: kill, kill -WINCH, kill -HUP, kill -KILL itp.

• Ponowne uruchomienie zatrzymanego procesu: fg

• Ponowne uruchomienie procesu w tle: bg

• Sprawdzenie listy działających procesów: jobs, a także ps

Programowanie Współbieżne, INE 5242, 2010/2011 2-3

Page 24: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Tworzenie nowych procesów

Tworzenie nowych procesów

• Do tworzenia nowych procesów służy funkcja fork() ze standardowej biblioteki libc.so.

• Nowy proces, utworzony funkcją fork() jest dokładną kopią rodzica i wykonuje się w tym samym miejscu – zawywołaniem funkcji fork()

printf("ok\n");a=7;p=fork();if (p==-1) { ...

printf("ok\n");a=7;p=fork();if (p==-1) { ...

printf("ok\n");a=7;p=fork();if (p==-1) { ...

printf("ok\n");a=7;p=fork();if (p==-1) { ...

pid=1234

pid=1234 pid=1240

• Oba procesy nie różnią się niczym, poza wartością zwróconą przez funkcję fork():

– rodzic: numer procesu potomnego

– dziecko: wartość 0

Programowanie Współbieżne, INE 5242, 2010/2011 2-4

Page 25: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Tworzenie nowych procesów

Tworzenie nowych procesów (c.d.)

• Sposobem na rozróżnienie obu procesów jest zbadanie wartości zwracanejprzez fork().

pid=fork();switch (pid) {case -1: fprintf(stderr, "Błąd fork!\n");

exit(1);

case 0: /* dziecko / child */printf("Tu pisze dziecko. pid rodzica=%d\n", getppid());break;

default: /* rodzic / parent */printf("To drukuje rodzic. pid dziecka=%d\n", pid);

}

• Inne funkcje: getpid(), getppid(), wait(), kill(), exec()

printf("ok\n");a=7;p=fork();if (p==-1) { ...

printf("ok\n");a=7;p=fork();if (p==-1) { ...

printf("ok\n");a=7;p=fork();if (p==-1) { ...

printf("ok\n");a=7;p=fork();if (p==-1) { ...

pid=1234

pid=1234 pid=1240

Programowanie Współbieżne, INE 5242, 2010/2011 2-5

Page 26: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Tworzenie nowych procesów

Funkcja fork()

• przydziela nowemu procesowi pozycjęw tablicy procesów

• przydziela nowemu procesowi nowy,unikalny identyfikator

• tworzy kopię kontekstu procesumacierzystego, kopiując segmentypamięci lub zwiększając licznik odwołańdo segmentu (np. współdzielonegosegmentu kodu)

• otwarte pliki rodzica pozostawia otwartew dziecku, a więc zwiększa liczniki wtablicy plików i i-węzłów

• przekazuje rodzicowi pid dziecka,a dziecku – wartość 0.

• nowy proces, choć nie był jeszcze nigdywykonywany, „budzi się” tak, jakbyzasnął w oczekiwaniu na zasób(wychodzi ze stanu uśpienia)

t�ry� b

� u� zy� t

�k.�

t�ry� b

� j

�a� d

�ra� .�

u� s�´p io ny� g� o t�o w� y�

fork()

w� y� w� ła� s� zc z.�

u� t�w� o rzo ny�

zo mb�ie�

Programowanie Współbieżne, INE 5242, 2010/2011 2-6

Page 27: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Tworzenie nowych procesów

Funkcje exec()

• Rodzina funkcji: execl(), execv(), execle(),execve(), execlp(), execvp()

• nazwa funkcji określa jednocześnie zakresprzekazywanych parametrów do nowegoprogramu (wektor argumentów, zmienneśrodowiskowe) oraz to, czy przeszukiwać ścieżkę(zmienną $PATH)

• 1. argument – rzeczywista ścieżka douruchamianego programu lub skryptu

• 2. argument i dalsze – paramentry wywołania

• Wywołanie nadpisuje w aktualnym kontekścieprocesu segmenty kodu, danych i stosu nowymprogramem i wykonanie funkcji main()

if ((pid=fork())==0) {execl("/bin/ls", "ls", "-la", "/tmp", NULL);printf("Błąd!!! Ta instrukcja nie ma prawa się wykonać!\n");

} else {wait(NULL);

}

Nowy program dziedziczy:

• numer procesu i numer procesu rodzicaoraz przynależność do grupy procesów

• wartość nice

• wartość umask

• priorytet

• uid, gid i przynależność do grup użyt-kowników

• katalog bieżący

• limity zasobów

• otwarte plikia

• kilka innych wartości dotyczących blokadna plikach, semaforów i obsługi sygnałów(man exec)

aniekoniecznie! – uwaga na fcntl() i FD CLOEXEC

Programowanie Współbieżne, INE 5242, 2010/2011 2-7

Page 28: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Sygnały

Sygnały

Pozwalają zasygnalizować wystąpienie sytuacji specjalnej, takiej jak:

• śmierć potomka (przez wywołanie exit() lub w inny sposób)

• wyjątek – np. próba dostępu do pamięci poza przyznany zakres adresów, próba zapisu do pamięci z atrybutemread-only, itp.

• niespodziewany błąd podczas wykonywania programu (np. pisanie do łącza, którego już nikt nie czyta)

• błąd, z którym system nie potrafi sobie poradzić, np. brakpamięci na wykonanie exec() gdy już zostały zwolnione staresegmenty programu

• pobudka, czyli SIGALARM wysyłany na życzenie procesuprzez system

• interakcja z terminalem – klawisz BREAK, SUSPEND, itp.

• wysłanie sygnału przez inny proces

• wykonywanie programu krok po kroku przez debugger

Sygnały są obsługiwane tylko przy przejściu między trybem jądrasystemu a trybem użytkownika

tryb u¿ytk.

tryb j–dra.

u¶piony gotowy

fork()

wyw‡aszcz.

utworzony

zombie

sprawd…

sprawd… i obs‡u¿

Programowanie Współbieżne, INE 5242, 2010/2011 2-8

Page 29: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Sygnały

• Listę dostępnych sygnałów można w każdym systemie sprawdzić pisząc kill -list lub przeglądając plik/usr/include/sys/signal.h lub /usr/include/signum.h

#define SIGHUP 1 /* hangup */#define SIGINT 2 /* interrupt (rubout) */#define SIGQUIT 3 /* quit (ASCII FS) */...#define SIGFPE 8 /* floating point exception */#define SIGKILL 9 /* kill (cannot be caught or ignored) */#define SIGBUS 10 /* bus error */#define SIGSEGV 11 /* segmentation violation */#define SIGSYS 12 /* bad argument to system call */#define SIGPIPE 13 /* write on a pipe with no one to read it */#define SIGALRM 14 /* alarm clock */#define SIGTERM 15 /* software termination signal from kill */#define SIGUSR1 16 /* user defined signal 1 */#define SIGUSR2 17 /* user defined signal 2 */...#define SIGLOST 37 /* resource lost (eg, record-lock lost) */...

• Część sygnałów jest domyślnie ignorowana, część powoduje zakończenie procesu

• Każdy sygnał z wyjątkiem SIGKILL i SIGSTOP można przechwycić, rejestrując odpowiednią funkcję obsługisygnału za pomocą signal() lub sigset()

• Jeśli funkcja przechwytująca ma ignorować sygnał, wystarczy wywołać signal(SIG IGN) lub sigignore()

• Funkcją sigpause(numer sygnału) można zawiesić proces aż do momentu otrzymania żądanego sygnału

• Na czas obsługi sygnału przyjmowanie sygnałów tego samego typu zostaje zablokowane automatycznie (adodatkowo inne sygnały można blokować i odblokowywać wołając sighold() i sigrelse())

Programowanie Współbieżne, INE 5242, 2010/2011 2-9

Page 30: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

2. Procesy Kończenie procesu

Grupy procesów

• grupę może stanowić np. interpreter poleceń (shell) i wszystkie procesy przez niego uruchamiane – naciśnięcieBREAK itp. wysyła sygnał nie tylko do wykonywanego procesu, ale i do interpretera.

• ustawienie grupy – funkcja setpgrp()

Kończenie procesu

• wait()

• exit()

• Zakończony proces staje się zombie i powoduje wysłanie do rodzica sygnału SIGCLD

• Wywołanie przez rodzica funkcji wait() pozwala odebrać status zwrócony przez exit()

• „uwolniony” zombie ostatecznie znika z systemu

• wywołanie wait(), gdy nie ma żadnego zombie, zawiesza proces, do momentu gdy któreś z dzieci zakończyżywot lub gdy już nie będzie żadnego. (Zawieszenie kończy się także po odebraniu sygnału przez proces).

Różne funkcje wait():

pid_t wait (int *status);pid_t waitpid (pid_t pid, int *status, int options);pid_t wait3 (int *status, int options, struct rusage *rusage);pid_t wait4 (pid_t pid, int *status, int options, struct rusage *rusage);

Programowanie Współbieżne, INE 5242, 2010/2011 2-10

Page 31: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Strumienie pipe

Strumienie pipe i FIFO

Strumienie pipe

• pozwalają łączyć spokrewnione ze sobąprocesy

• transmisja jednokierunkowa

• z reguły łączą wyjście stdout jednegoprocesu z wejściem stdin innego

• tworzone funkcją pipe(int fd[2]) –wypełnia 2-elementową tablicędeskryptorów

• fd[1] jest końcem otwartym do pisania

proces 2

jadro systemuj–dro systemu

fd[1] fd[0]

proces 1

• fd[0] jest końcem otwartym do czytania

• oba końce to „zwykłe” deskryptory plików – można na nich operować takimi funkcjami jak read(), write(),fprintf (), czy close().

• jądro systemu gwarantuje, że operacje zapisu nie przekraczające rozmiaru strumienia są niepodzielne

Programowanie Współbieżne, INE 5242, 2010/2011 3-1

Page 32: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Pisanie do strumienia pipe

Pisanie do strumienia pipe

proces 2

jadro systemuj–dro systemu

fd[1] fd[0]

proces 1

• strumień pipe pełni jednocześnie rolę bufora o pojemności 4kB

• zapisanie danych, gdy jest miejsce w strumieniu, powoduje natychmiastowy powrót z funkcji write() itp.

• zapisanie danych powyżej maksymalnego rozmiaru powoduje zablokowanie procesu, do czasu aż zwolni sięmiejsce w strumieniu (ktoś te dane przeczyta)

• za pomocą odpowiednich funkcji fcntl() lub ioctl() można ustawić opcję O_NDELAY, lecz wówczas proces piszącymusi być przygotowany na to, że może mu się udać zapis tylko części wysyłanych danych

• pisanie do strumienia, którego nikt nie czyta (jego drugi koniec został zamknięty) powoduje wysłanie doprocesu piszącego sygnału SIGPIPE

• zamknięcie zapisywanego końca powoduje, że proces czytający w wyniku wywołania funkcji read() otrzymawartość 0

Programowanie Współbieżne, INE 5242, 2010/2011 3-2

Page 33: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Czytanie ze strumienia pipe

Czytanie ze strumienia pipe

• otrzymywane dane stanowią strumień nie podzielony na żadnepakiety lub inne fragmenty

• czytanie ze strumienia może zwrócić mniej danych, niżzażądano

• jeśli strumień jest pusty i zamknięty do zapisu, funkcja read()zwraca wartość 0, oznaczającą EOF.

• jeśli strumień jest pusty, ale otwarty do zapisu, funkcja read()zostaje zablokowana, do momentu gdy można będzie cośprzeczytać

• blokowania można uniknąć stosując opcję O_NDELAY w funkcjifcntl() lub korzystając z funkcji select()

• zamknięcie strumienia do odczytu, gdy ciągle znajdowały sięw nim nie przeczytane dane, generuje sygnał SIGPIPEwysyłany do procesu piszącego

• zamknięcie pustego strumienia danych nie powoduje żadnychkonsekwencji dla procesu piszącego – dopóki nie spróbujeczegoś zapisać.

• dzięki blokowaniu możliwe jest wykorzystanie strumieni dowzajemnej synchronizacji procesów

proces 2

jadro systemuj–dro systemu

fd[1] fd[0]

proces 1

Programowanie Współbieżne, INE 5242, 2010/2011 3-3

Page 34: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Łączenie dwóch procesów strumieniem pipe

Łączenie dwóch procesów strumieniem pipe

fd[1] fd[0]

proces potomny

jadro systemu

proces

proces

j–dro systemu

fd[1] fd[1]

fd[0] fd[0]

fd[1] fd[0]

j–dro systemu

int fd[2];if (pipe(fd)==-1) perror("pipe");...

switch (p=fork()){ case 0: /*dziecko*/ ... break; default: /*rodzic*/ ...}

Programowanie Współbieżne, INE 5242, 2010/2011 3-4

Page 35: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Łączenie dwóch procesów strumieniem pipe

Łączenie dwóch procesów strumieniem pipe (c.d.)

proces potomny

jadro systemu

proces

j±dro systemu

fd[1]

fd[0]

fd[1] fd[0]

/*rodzic*/

close(fd[0]);write(fd[1], buf, strlen(buf)+1);

/*dziecko*/

close(fd[1]);n=read(fd[0], buf, BUFSIZE);

proces potomny

jadro systemujadro systemu

proces

j±dro systemu

fd[1] fd[1]

fd[0] fd[0]

fd[1] fd[0]

switch (p=fork()){ case 0: /*dziecko*/ ... break; default: /*rodzic*/ ...}

Programowanie Współbieżne, INE 5242, 2010/2011 3-5

Page 36: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Tworzenie strumieni stdout-stdin

Tworzenie strumieni stdout-stdin

• Do kopiowania otwartych deskryptorów służą funkcje dup() i dup2 ()

• dup(n) kopiuje deskryptor n na najniższy wolny numer deskryptora

• Poniższy program:

int fdes;fdes=open("/tmp/test", "rt");close(0);dup(fdes);

spowoduje przepisanie deskryptora fdes do deskryptora nr 0.

• to samo można osiągnąć za pomocą dup2 (fdes, 0)

Jak korzystając z dup() uzyskać efekt taki sam jak w dup2 (fdes, 10)?

Programowanie Współbieżne, INE 5242, 2010/2011 3-6

Page 37: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Tworzenie strumieni stdout-stdin

Tworzenie strumieni stdout-stdin

Najczęstszym zastosowaniem jest zastąpienie standardowego wejścia (lub wyjścia) strumieniem pipe, przed wyko-naniem funkcji exec():

int fd[2];

pipe(fd);if ((f=fork()) == 0) {/* dziecko -- będzie czytać */close(fd[1]);close(0);dup(fd[0]);execlp("cat", "cat", "-n", NULL);fprintf(stderr, "exec się nie udał!\n");exit(1);

} else {/* rodzic lub błąd fork() */...wait();

}

Programowanie Współbieżne, INE 5242, 2010/2011 3-7

Page 38: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Funkcja popen()

Funkcja popen()

Podobny efekt można osiągnąć za pomocą funkcji popen():

#include <stdio.h>FILE *popen(const char *command, const char *mode);int pclose(FILE *stream);

• popen() tworzy strumień pipe oraz proces potomny, w którym wykonuje /bin/sh, przekazując mu jako para-mentr nazwę programu do wykonania

• jeśli *type==’r’, to standardowe wyjście uruchomionego podprocesu jest połączone ze strumieniem, a procesgłówny może czytać ze zwróconego deskryptora

• jeśli *type==’w’, zwrócony koniec jest otwarty do zapisu i połączony ze standardowym wejściem uruchomio-nego podprocesu

• zakończenie komunikacji może wymagać użycia pclose(), konieczna też jest synchronizacja za pomocą wait().

Wady stosowania popen():

• za każdym razem niepotrzebnie uruchamiany jest /bin/sh;

• brak pełnej kontroli nad wejściem i wyjściem z podprocesu;

• nie jest możliwe jednoczesne przechwycenie wejścia i wyjścia ani rozdzielenie std. wyjścia od wyjścia błędów;

• funkcja popen() NIGDY i pod żadnym pozorem nie powinna być stosowana w programach typu set-user-id(zbyt łatwo przeoczyć złe dane przekazywane do interpretera sh).

Programowanie Współbieżne, INE 5242, 2010/2011 3-8

Page 39: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Strumienie FIFO

Strumienie FIFO

Zasadnicze różnice w stosunku do strumieni pipe:

• Posiadają dowiązanie w systemie plików – tworzone funkcją mknod() lub komendą mknod.

• Mogą być używane przez procesy nie spokrewnione ze sobą, a nawet procesy różnych użytkowników.

• Funkcja open() używana do otwierania kolejki FIFO do zapisu blokuje proces, aż do momentu otwarcia kolejkido odczytu, i odwrotnie. Dopiero gdy kolejka otwarta jest jednocześnie do zapisu i odczytu obie funkcje open()powracają ze stanu uśpienia;

• „Sprzątanie” tymczasowych kolejek może wymagać usunięcia ich z systemu plików funkcją unlink().

• Kolejki FIFO mają z reguły większy rozmiar bufora (4–16 kB)

Podobieństwa:

• Zamknięcie końca używanego do pisania (dokładniej: wszystkich końców) generuje u czytelników EOF;

• Zamknięcie końca używanego do czytania generuje sygnał SIGPIPE wysyłany do wszystkich piszących dostrumienia;

• Zapis i odczyt przez standardowe funkcje I/O, takie jak write() czy read();

• Niepodzielność zapisów mniejszych niż rozmiar strumienia;

• Blokowanie procesów w przypadku przepełnienia lub pustego strumienia (i możliwość zastosowania O_NDELAY).

Programowanie Współbieżne, INE 5242, 2010/2011 3-9

Page 40: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

3. Strumienie pipe i FIFO Korzystanie ze strumieni FIFO

Korzystanie ze strumieni FIFO

#include <stdio.h>#include <errno.h>

main(){ int fd;int err;

err=mknod("/tmp/fifo1", S_IFIFO | 0660, 0)if (err<0 && errno!=EEXIST) {fprintf(stderr, "Nie mogę utworzyć FIFO\n");exit (1);

}

fd=open("/tmp/fifo1, O_RDONLY); /* blokada? */if (fd<0) {fprintf(stderr, "Nie mogę otworzyć FIFO do czytania\n");exit(2);

}

read(fd, ... ...);...close(fd);unlink("/tmp/fifo1");

}

Programowanie Współbieżne, INE 5242, 2010/2011 3-1

Page 41: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

4. Kolejki komunikatów

Kolejki komunikatów

• lista (jednokierunkowa) zawierająca komunikaty o określonym maksymalnym rozmiarze;

• nowe komunikaty dodawane są na końcu listy, zachowując kolejność ich wysyłania

• każdy komunikat ma dodatkowy parametr zwany typem, co pozwala na obsługę kilku „strumieni” komunikatóww ramach jednej kolejki (poprzez selektywne odbieranie komunikatów wybranego typu).

msgsnd()

msgrcv()

kolejkakomunikat�w(w przestrzenij–dra systemu)

5

5

3

2

2

2

15

37

2

3

3

2

7

2

2

Programowanie Współbieżne, INE 5242, 2010/2011 4-2

Page 42: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

4. Kolejki komunikatów Struktura kolejki w jądrze systemu

Struktura kolejki w jądrze systemu

• cuid i cgid – proces, który utworzyłkolejkę (creator uid, creator gid);

• uid i gid – aktualny właścicieli właściciel grupowy kolejki;

• mode – prawa dostępu do kolejki;

• key – klucz identyfikujący kolejkę;

• first, last – wskaźniki na pierwszyi ostatni komunikat w kolejce;

• wielkość całej kolejki nie możeprzekraczać msg_qbytes, a aktualnawielkość to msg_cbytes;

• aktualna liczba komunikatóww kolejce to msg_qnum.

type: 7

next:

len: 5

data

type: 3

next:

len: 10

data

type: 2

next:

len: 3

data

NULL

nag‡�wki komunikat�w

obszar danychmsg 1

msg 2

msg 3

struct ipc_perm msg_perm;

struct msg *first;

struct msg *last;

time_t msg_rtime;

time_t msg_ctime;

...

uid_t cuid; gid_t cgid; uid_t uid; gid_t gid; mode_t mode; ... key_t key;

ulong_t msg_cbytes;

ulong_t msg_qnum;

ulong_t msg_qbytes;

struktura msqid

Programowanie Współbieżne, INE 5242, 2010/2011 4-3

Page 43: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

4. Kolejki komunikatów Tworzenie kolejek

Tworzenie kolejek

int msgget(key_t key, int msgflg);

Funkcja msgget() tworzy nową kolejkę lub znajduje już istniejącą

• Jeśli klucz ma wartość IPC_PRIVATE, zawsze jest tworzona nowa kolejka.

• Jeśli kolejka o podanym kluczu już istnieje, zostaje zwrócony jej identyfikator, o ile użytkownik ma odpowiednieprawa dostępu, w przeciwnym razie zwracany jest (poprzez zmienną errno) błąd ENOENT;

• Jeśli kolejka nie istnieje a wśród opcji msgflg ustawiona była IPC_CREAT, zostaje utworzona nowa kolejkai zwrócony jej identyfikator;

• Użycie opcji IPC_EXCL wymuszautworzenie nowej kolejki – jeżeli byłyustawione obie opcje: IPC_CREATi IPC_EXCL, a kolejka już istniała,zostaje zwrócony błąd EEXIST.

Jeśli tworzona jest nowa kolejka, najmłodsze9 bitów w opcjach oznacza prawa dostępu dotworzonej kolejki, np. 0644 albo 0666.

#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>

#define KEY ((key_t) 12345L)#define PERM 0600

main(){int msqid;

if ( (msqid=msgget(KEY, PERM | IPC_CREAT)) < 0) {fprintf(stderr, "Nie można utworzyć kolejki\n");exit (1);

}...

}

Programowanie Współbieżne, INE 5242, 2010/2011 4-4

Page 44: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

4. Kolejki komunikatów Usuwanie kolejek

Usuwanie kolejek

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

Funkcja msgctl() pozwala usunąć kolejkę, ale także sprawdzić jej stan lub zmienić pewne wartości związane zkolejką. Sposób działania zależy od parametru cmd:

• IPC_STAT – umieszcza dane o kolejce w strukturze wskazywanej przez buf;

• IPC_SET – zmienia parametry kolejki na parametry przekazane w strukturze wskazywanej przez buf. Zmienionemogą zostać: właściciel i grupa (o ile wołający proces ma uid=0 lub taki sam, jak proces, który utworzyłkolejkę), prawa dostępu do kolejki i maksymalny rozmiar kolejki;

• IPC_RMID – usuwa kolejkę z systemu.

Polecenia systemowe związane z kolejkami komunikatów:

• ipcrm – usuwa kolejkę

• ipcs -q – sprawdza status kolejki

Programowanie Współbieżne, INE 5242, 2010/2011 4-5

Page 45: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

4. Kolejki komunikatów Wysyłanie komunikatów

Wysyłanie komunikatów

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

struct mymsg { /* przykładowa struktura komunikatu */long mtype; /* typ komunikatu */char mtext[1]; /* zawartość komunikatu */

}

• Wysyłając komunikat należy określić jego długość i adres początku;

• msgflg może mieć ustawiony bit IPC_NOWAIT, oznaczający, że funkcja nie będzie blokowana, jeśli komunikatunie można wysłać natychmiast;

• Wysyłany komunikat musi mieć określony typ – liczba dodatnia na samym początku struktury przechowującejkomunikat;

• Struktura zawierająca komunikat może być dowolna, ale pierwsze pole musi być liczbą typu long, zawierającątyp komunikatu.

struct komunikat {long type;int x;int y;char opis[30];

}

Programowanie Współbieżne, INE 5242, 2010/2011 4-6

Page 46: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

4. Kolejki komunikatów Wysyłanie komunikatów

Wysyłanie komunikatów – przykład

#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>

#define KEY ((key_t) 12345L)#define PERM 0600

struct komunikat {long type;int x;int y;char opis[30];

}

main(){int mq;int res;

struct komunikat msg={12, 1, 2, "abc");

mq=msgget(KEY, IPC_CREAT | 0644);if (mq==-1) {.... /* błąd utworzenia kolejki */

}res=msgsnd(mq, &msg, sizeof(msg)-sizeof(long int), 0);

}

Programowanie Współbieżne, INE 5242, 2010/2011 4-7

Page 47: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

4. Kolejki komunikatów Odbieranie komunikatów

Odbieranie komunikatów

int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

Wartość msgtyp określa jakie komunikaty mogą zostać odebrane:

• 0 – pierwszy komunikat z kolejki, dowolnego typu;

• > 0 – pierwszy komunikat o podanym typie;

• < 0 – spośród komunikatów, których typ jest mniejszy lub równy wartości bezwzględnej msgtyp, wybieranyjest komunikat o najniższym typie (a jeśli jest ich kilka – pierwszy z nich).

Wartość msgflg określa sposób zachowania funkcji:

• jeśli ustawiony jest znacznik IPC_NOWAIT, a w kolejce nie ma żądanego komunikatu, funkcja wróci natychmiast,zwracając wartość -1 i ustawiając zmienną errno na ENOMSG;

• jeśli IPC_NOWAIT nie jest ustawiony, a w kolejce brak żądanego komunikatu, funkcja usypia proces, do czasu gdy:

– zostanie wysłany odpowiedni komunikat;

– kolejka zostanie usunięta z systemu (błąd EIDRM);

– zostanie odebrany sygnał, który nie jest ignorowany. Komunikat nie jest pobierany z kolejki a funkcjamsgrcv() zwraca błąd EINTR lub jest automatycznie restartowana (sigaction(), parametr SA_RESTART).

• jeśli ustawiony jest znacznik MSG_NOERROR, funkcja nie będzie sygnalizować błędu, jeśli odbierany komunikatjest większy niż długość przekazanego bufora, przycinając go do żądanego rozmiaru. W przeciwnym raziekomunikat nie zostanie odebrany a zmienna errno zostanie ustawiona na E2BIG.

Programowanie Współbieżne, INE 5242, 2010/2011 4-8

Page 48: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

4. Kolejki komunikatów Selektywne przesyłanie komunikatów

Selektywne przesyłanie komunikatów

k�o� l

�e� j

�k

�a�

k�o� m� u� n� i

k

�a� t �w�

2

3

2

2

2

15

37

2

3

3

2

7

klie� nt 1 klie� nt

2 klie� nt

3

s� e� rw� e� r

2 7 2 3 2 15

23715

• klienci przesyłają komunikaty do serwera oznaczając je typem 2 (lub np. 1 dla danych o wyższym priorytecie,2 – normalnym);

• serwer odbiera wyłącznie komunikaty o typie 2 (lub 1–2), a wysyła komunikaty innych typów;

• każdy klient ma osobny numer dla komunikatów, które odbiera (np. swój numer procesu).

Programowanie Współbieżne, INE 5242, 2010/2011 4-9

Page 49: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Sekcja krytyczna

Semafory

Sekcja krytyczna

Dwa procesy niezależnie modyfikująwspólną zmienną „a”, jeden po drugim

a� == 5�0�0�

int a,b;

b=a;b+=100;a=b;

500

600 int a,c;

c=a;c+=300;a=c;

900

600a� == 6�0�0�

a� == 9�0�0�

a� == 5�0�0

int a,c;

c=a;c+=300;a=b;

500

600

int a,b;

b=a;

800

500

a� == 8�0�0

a� == 6�0�0

b+=100;a=b;

Dwa procesy niezależnie modyfikująwspólną zmienną „a”, lecz system ope-racyjny powoduje chwilowe wstrzymaniepierwszego procesu w trakcie wykonywa-nia tej operacji.

Programowanie Współbieżne, INE 5242, 2010/2011 5-1

Page 50: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Sekcja krytyczna

• Od momentu pobrania wartości zmiennej „a” do momentu jej odesłania żaden inny proces nie powinien miećdo niej dostępu

• Fragment programu potrzebujący wyłączności działania nazwiemy sekcją krytyczną.

int a,b;

b=a;

b+=100;a=b;

int a,c;

c=a;c+=300;a=c;

Rozwiązanie?

static int wolny=1; /* semafor */

Zajmij(int *wolny) { Zwolnij(int *wolny) { main() {while (*wolny<=0) *wolny++; int a, b;sleep(1); } Zajmij(&sem); // Dlaczego*wolny--; b=a; // to nie} b+=100; // działa ?

a=b;Zwolnij(&sem);}

Programowanie Współbieżne, INE 5242, 2010/2011 5-2

Page 51: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Sekcja krytyczna

To będzie działać, jeśli operacje Zajmij () i Zwolnij () będą niepodzielne.

int a,b;

Zajmij(s);

int a,c;

Zajmij(s);

Zwolnij(s);

Zwolnij(s);

c=a;c+=300;a=c;

b=a;

b+=100;a=b;

• Operacja Zajmij () jest wejściem do sekcji krytycznej – usypia proces, jeśli zasób jużjest zajęty, aż do momentu, gdy inny proces go zwolni. Proces zostaje umieszczonyw kolejce procesów oczekujących na zwolnienie zasobu (semafora);

• Operacja Zwolnij () stanowi wyjście z sekcji krytycznej – nigdy nie usypia procesu, zato może spowodować obudzenie innego (przeniesienie go z kolejki oczekujących).

• Obie operacje są niepodzielne (atomowe) i działają na poziomie jądra systemu.

t�ry� b

� u� zy� t

�k.�

t�ry� b

� j

�a� d

�ra� .�

u� s�´p io ny� g� o t�o w� y�

Programowanie Współbieżne, INE 5242, 2010/2011 5-3

Page 52: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Sekcja krytyczna

Semafor możemy traktować jak abstrakcyjny typ danych składający się ze zmiennej i kolejki procesów:

• Zajmij (S)

Jeśli S > 0, to S ← S − 1 i idź dalej.

Jeśli S = 0, to umieść proces w kolejce oczekujących na zwolnienie semafora i zaśnij.

• Zwolnij (S)

Jeśli kolejka oczekujących jest pusta, to S ← S + 1:

Jeśli ktoś czeka, to usuń go z kolejki oczekujących i obudź go, nie zmieniając wartości S.

Semafor binarny – przyjmujący jedynie wartości 0 i 1.

Semafor ogólny – przymujące dowolne (lub wybrane) wartości nieujemne

• Bieżąca wartość semafora odpowiada liczbie „wolnych” zasobów;

• Osiągnięcie wartości 0 oznacza, że kolejny proces żądający zasobu zostanie uśpiony;

• Możliwe jest zmniejszenie lub zwiększenie wartości semafora o wartość inną niż 1 (o ile zmniejszenie niedoprowadziłoby do osiągnięcia wartości ujemnej).

Programowanie Współbieżne, INE 5242, 2010/2011 5-4

Page 53: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Sekcja krytyczna

Inne przykłady wymagające ochrony dostępu do sekcji krytycznej:

• modyfikacja wspólnej zmiennej w pamięci lub pliku (konto bankowe?);

• zapis pliku przez kilka procesów;

• modyfikacja rekordu w bazie danych;

• dostęp do urządzeń zewnętrznych (terminale, modemy, itp.);

Inne przykłady synchronizacji za pomocą semaforów:

• Producent-konsument

– jeden proces „produkuje” dane i sygnalizuje to zwalniając semafor:

– drugi „konsumuje” je, oczekując na nie przez zajęcie semafora.

• Synchronizacja kilku procesów w oczekiwaniu na jedno wspólne wydarzenie

Programowanie Współbieżne, INE 5242, 2010/2011 5-5

Page 54: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Problem pięciu filozofów

Problem pięciu filozofów

• Życie filozofa to medytacje, ale to wyczerpującezajęcie, więc filozof czasami robi się głodny;

• Głodny filozof udaje się do jadalni i zajmuje miejsceprzy stole;

• Filozof je tylko wtedy, gdy ma dwa widelce;

• Dwóch filozofów nie może jednocześnie trzymaćtego samego widelca;

• Najedzony filozof wychodzi z jadalni i wracamedytować.

Problemy:

• Żaden filozof nie powinien zostać zagłodzony.

• Nie można dopuścić do blokady.

• Problem higieny pomijamy, jako nie wnoszący nicdo rozwiązania.

1

2

3

4

5

Programowanie Współbieżne, INE 5242, 2010/2011 5-6

Page 55: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Tworzenie semaforów

Tworzenie semaforów

int semget(key_t key, int n_sems, int semflg);

Funkcja semget() tworzy nowy zbiór semaforów lub znajduje już istniejący:

• Jeśli klucz ma wartość IPC_PRIVATE, zawsze jest tworzony nowy zbiór semaforów;

• Jeśli semafor o podanym kluczu już istnieje, zostaje zwrócony jego identyfikator, o ile użytkownik ma odpo-wiednie prawa dostępu do niego, w przeciwnym razie zwracany jest (poprzez zmienną errno) błąd ENOENT;

• Jeśli semafor nie istnieje, a wśród opcji semflg ustawiona była IPC_CREAT, zostaje utworzony nowy semafori zwrócony jego identyfikator;

• Użycie opcji IPC_EXCL wymuszautworzenie nowego semafora – jeżelibyły ustawione obie opcje: IPC_CREATi IPC_EXCL, a semafor już istniał, zostajezwrócony błąd EEXIST.

Jeśli tworzony jest nowy semafor, najmłodsze9 bitów w opcjach oznacza prawa dostępu dotworzonego semafora, np. 0644 albo 0666.

#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>

#define KEY ((key_t) 12345L)#define PERM 0600

main(){int semid;if ( (semid=semget(KEY, 1, PERM | IPC_CREAT)) < 0) {fprintf(stderr, "Nie można utworzyć semafora\n");exit (1);

}...

}

Programowanie Współbieżne, INE 5242, 2010/2011 5-7

Page 56: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Usuwanie semaforów

Usuwanie semaforów

int semctl(int semid, int semnum, int cmd, union semun arg);

union semun {int val;struct semid_ds *buf;ushort_t *array;} arg ;

Funkcja semctl() pozwala usunąć semafor, ale także wykonać na nim różne operacje. Sposób działania zależy odparametru cmd, a parametr semnum określa numer semafora w grupie, którego dotyczy operacja (przy pierwszych 3operacjach, dotyczących całej grupy, ten parametr jest nieistotny):

• IPC_STAT – umieszcza dane o semaforze (właściciel, prawa dostępu, itp.) w strukturze wskazywanej przez buf;

• IPC_SET – zmienia parametry grupy semaforów na parametry przekazane w strukturze wskazywanej przez buf.Zmienione mogą zostać: właściciel i grupa (o ile wołający proces ma uid=0 lub taki sam, jak proces, któryutworzył semafor) i prawa dostępu do semafora.

• IPC_RMID – usuwa grupę semaforów z systemu.

• GETVAL – pobiera i zwraca wartość semafora semnum;

• SETVAL – ustawia wartość semafora semnum na wartość val unii semun przekazanej jako argument arg;

Polecenia systemowe związane z semaforami:

• ipcrm – usuwa semafor (grupę semaforów) z systemu; ipcs -s – sprawdza status semafora.

Programowanie Współbieżne, INE 5242, 2010/2011 5-8

Page 57: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Zajmowanie i zwalnianie semaforów

Zajmowanie i zwalnianie semaforów

int semop(int semid, struct sembuf *sops, size_t nsops);

struct sembuf {short sem_num; /* numer semafora */short sem_op; /* operacja na semaforze */short sem_flg; /* opcje */}

Ogólnie:

• sem_op < 0 – zajęcie semafora

• sem_op > 0 – zwolnienie semafora

• sem_op == 0 – synchronizacja z semaforem (oczekiwanie, aż jego wartość osiągnie 0)

Opcje sem_flg:

• IPC_NOWAITJeżeli nie można wykonać żądanej operacji, proces nie zostaje uśpiony, lecz funkcja wraca z błędem EAGAIN

• SEM_UNDOJeżeli semafor zostaje przydzielony, liczba, o jaką została zmniejszona jego wartość, zostaje dodana do zmiennejsemadj procesu (a przy zwalnianiu semafora – odjęta od tej zmiennej).

Jeśli proces zostaje zakończony z niezerową wartością semadj (np. po otrzymaniu sygnału itp.), funkcja exit()spowoduje dodanie tej zmiennej do wartości semafora (czyli zwolnienie zajętych zasobów).

Programowanie Współbieżne, INE 5242, 2010/2011 5-9

Page 58: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Zajęcie semafora

Zajęcie semafora

struct sembuf op_zajm={0, /* semafor nr 0 */-1, /* zajmij == odejmij wartość |N| (tutaj: 1) */0 /* opcje */

};int semid;

semid=semget(IPC_PRIVATE, 1, IPC_CREAT);if (semid==-1)... (błąd) ...

semop(semid, &op_zajm, 1);/* sekcja krytyczna */

Algorytm zajmowania semafora (N < 0):

• jeśli wartość semafora jest większa lub równa wartości bezwzględnej N , to zmniejsz ją o tyle (a jeśli użytoopcji SEM_UNDO, to dodatkowo zwiększ o |N | zmienną semadj).

• jeśli nie, i nie została użyta opcja IPC_NOWAIT, zwiększ licznik procesów oczekujących na semafor i zawieśproces, aż do czasu, gdy nastąpi jedno ze zdarzeń:

– zostanie spełniony ten warunek. Wówczas wartość semafora jest pomniejszana o |N | (i ew. zwiększana o|N | wartość semadj), zmniejszany jest licznik procesów oczekujących, a proces zostaje obudzony.

– semafor zostanie usunięty z systemu;

– proces otrzyma sygnał (funkcja zwróci błąd EINTR lub zostanie automatycznie wznowiona).

• jeśli nie było możliwe zajęcie semafora, ale użyto opcji IPC_NOWAIT, wróć natychmiast z błędem EAGAIN.

Programowanie Współbieżne, INE 5242, 2010/2011 5-10

Page 59: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Zwolnienie semafora

Zwolnienie semafora

struct sembuf op_tab[2]={0, /* semafor nr 0 */-1, /* zajmij == odejmij wartość |N| (tutaj: 1) */0 /* opcje */

}, {0, /* semafor nr 0 */1, /* zwolnij == dodaj wartość |N| (tutaj: 1) */0 /* opcje */

};int semid;

semid=semget(IPC_PRIVATE, 1, IPC_CREAT);if (semid==-1)... (błąd) ...

semop(semid, op_tab, 1);/* sekcja krytyczna *//* ... */

semop(semid, &(op_tab[1]), 1);

Algorytm zwalniania semafora przez system operacyjny (N > 0):

• wartość semafora zostaje zwiększona o N ,

• jeśli ustawiona jest opcja SEM_UNDO, wartość ta jest również odejmowana od zmiennej semadj procesu związanejz tym semaforem,

• jeśli licznik procesów oczekujących na semafor ma wartość większą od zera, zostaje obudzony pierwszy procesz kolejki.

Programowanie Współbieżne, INE 5242, 2010/2011 5-11

Page 60: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

5. Semafory Oczekiwanie na zajęcie semafora przez inny proces

Oczekiwanie na zajęcie semafora przez inny proces

Jeśli wartość N jest równa 0, proces oczekuje aż semafor zostanie zajęty przez inny proces:

• jeśli wartość semafora wynosi 0, funkcja semop() wraca natychmiast;

• jeśli wartość semafora jest większa od 0, ale użyto opcji IPC_NOWAIT, funkcja natychmiast wraca z błędemEAGAIN;

• jeśli wartość semafora jest większa od 0 i nie użyto opcji IPC_NOWAIT, zostaje zwiększona wartość semzcntsemafora, a proces zostaje uśpiony, do czasu, gdy:

– wartość semafora (semval) osiągnie zero;

– semafor zostanie usunięty z systemu;

– proces otrzyma sygnał, który ma zostać przechwycony. Wówczas wartość semzcnt jest zmniejszana i wołanaprocedura obsługi sygnału zarejestrowana wcześniej wywołaniem funkcji signal().

Zastosowania dla tego typu postępowania:

• Rozwiązanie problemu wyścigu podczas inicjowania wartości semafora.

• Synchronizacja z procesem żądającym dostępu do zasobu (jednoczesna operacja typu „czekaj, aż osiągnie 0, agdy się to stanie, zwolnij”).

Programowanie Współbieżne, INE 5242, 2010/2011 5-12

Page 61: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Stronicowanie pamięci

Pamięć wspólna

Stronicowanie pamięci

• Adresy wkompilowane w programy nie mogąbyć adresami pamięci fizycznej, bo nie byłobymożliwe współbieżne wykonywanie kilkuprocesów.

• Kompilatory generują kod operujący wwirtualnej przestrzeni adresowej (ograniczonejz góry, np. do 4GB), a tłumaczenia adresówwirtualnych na rzeczywiste dokonujejednostka MMU procesora.

• System może wykonywać kilka kopii tegosamego programu, operującego tymi samymiadresami pamięci wirtualnej, więc tłumaczenieadresów wirtualnych na fizyczne jest ściślezwiązane z kontekstem procesu.

• Pamięć wirtualna uzyskiwana jest przezsegmentację i stronicowanie. Jednostkowymobszarem pamięci jest strona, zwykle wielkościod 8 do 32 kB (stały rozmiar zależny odsystemu).

20� b

�i�t� 12 b

�i�t�

0 0 1 A 7 3 F 0

8F345000 RWX

n� r s� t� ro� n� y� o� f�f

�s� e t�

t� a b�l�i�c� a s� t� ro� n�

8CF04000 R--81212000 R--8DD22000 R-X... RWX8CF1A000 RW-8CF1B000 RW-

1A7

8CF1A000

8CF1B000

8CF19000

3F0

8C000000

p a m� i�Œ�

� f�i

�z� y� c� z� n� a

o� b�s� z� a r

p ro� c� e s� u�

s� t� r� on� ap�am� iŒ

ci

Programowanie Współbieżne, INE 5242, 2010/2011 6-1

Page 62: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Segmentacja pamięci

Segmentacja pamięci

W rzeczywistości dostęp do pamięci jest trochę bardziej skomplikowany. Dostęp do pamięci fizycznej odbywa sięw pierwszym rzędzie poprzez segmenty (danych, kodu, stosu), a dopiero potem – strony:

20� b

�i

�t� 12 b

�i

�t�

1 A 7 3 F 0

s� e� g� m� e� n� t� i� n� r s� t� ro n� y o f

�f

�s� e� t�

t� a� b�l i

�c� a� s� t� ro n�

8CF04000 R--

... ...8CF1A000 RW-8CF1B000 RW-

8CF1A000

8CF1B000

8CF19000

3F0

8C000000

p� a� m� i�Œ�

� f�i�z� y c� z� n� a�

o b�s� z� a� r

p� ro c� e� s� u�

tablica s� eg� m� en� tów�

8F345000 RWX

81212000 R--

8DD22000 R-X... ...8CF1B000 R-X

8FAA5000 RW-8FAA6000 RW-... ...8FAD1000 RW-

0 0

k�od

d�

an� e

s� tos�

k�od

d�

an� e

s� tos�

• Każdy segment posiada własną tablicę stron (adres tablicy i jej długość);

• segment reprezentuje ciągły obszar pamięci;

Programowanie Współbieżne, INE 5242, 2010/2011 6-2

Page 63: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Segmentacja pamięci

• przy każdym dostępie do pamięci starsza część adresu wyznacza używany segment, a jednocześnie jest porów-nywana z jego wielkością, w celu wykrycia dostępu poza przydzielony segment;

• starsza część adresu wyznacza indeks w tablicy stron segmentu i pozwala odczytać adres strony pamięcifizycznej;

• ostateczny adres powstaje przez zsumowanie adresu strony i offsetu.

20� b

�i

�t� 12 b

�i

�t�

1 A 7 3 F 0

s� e� g� m� e� n� t� i� n� r s� t� ro n� y o f

�f

�s� e� t�

t� a� b�l i�c� a� s� t� ro n�

8CF04000 R--

... ...8CF1A000 RW-8CF1B000 RW-

8CF1A000

8CF1B000

8CF19000

3F0

8C000000

p� a� m� i�Œ�

� f�i�z� y c� z� n� a�

o b�s� z� a� r

p� ro c� e� s� u�

tablica s� eg� m� en� tów�

8F345000 RWX

81212000 R--

8DD22000 R-X... ...8CF1B000 R-X

8FAA5000 RW-8FAA6000 RW-... ...8FAD1000 RW-

0 0

k�od

d�

an� e

s� tos�

k�od

d�

an� e

s� tos�

Programowanie Współbieżne, INE 5242, 2010/2011 6-3

Page 64: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Tworzenie segmentu pamięci wspólnej

Tworzenie segmentu pamięci wspólnej

int shmget(key_t key, int size, int shmflg);

Funkcja shmget() tworzy nowy segment pamięci wspólnej lub znajduje już istniejący:

• Jeśli klucz ma wartość IPC_PRIVATE, tworzony jest nowy segment;

• Jeśli segment o podanym kluczu już istnieje, zostaje zwrócony jego identyfikator, o ile użytkownik ma odpo-wiednie prawa dostępu do niego, w przeciwnym razie zwracany jest (poprzez zmienną errno) błąd ENOENT;

• Jeśli segment pamięci wspólnej nie istnieje,a wśród opcji shmflg ustawiona byłaIPC_CREAT, zostaje utworzony nowy blokpamięci i zwrócony jego identyfikator;

• Użycie opcji IPC_EXCL wymusza utworzenienowego segmentu pamięci – jeżeli byłyustawione obie opcje: IPC_CREAT iIPC_EXCL, a segment już istniał, zostajezwrócony błąd EEXIST.

Jeśli tworzony jest nowy segment pamięci,najmłodsze 9 bitów w opcjach oznacza prawadostępu do tworzonego bloku pamięci, np. 0644albo 0666.

#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#define KEY ((key_t) 12345L)#define PERM 0600#define SIZE 4096

main(){int shmid;

if ( (shmid=shmget(KEY, SIZE, PERM | IPC_CREAT)) < 0) {fprintf(stderr, "Nie można utworzyć bloku pamięci wspólnej\n");exit (1);

}...

}

Programowanie Współbieżne, INE 5242, 2010/2011 6-4

Page 65: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Usuwanie pamięci wspólnej

Usuwanie pamięci wspólnej

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

Funkcja shmctl() pozwala usunąć segment pamięci wspólnej, ale także wykonać na nim różne operacje. Sposóbdziałania zależy od parametru cmd:

• IPC_STAT – umieszcza dane o bloku pamięci (takie jak właściciel, prawa dostępu, itp.) w strukturze wskazy-wanej przez buf;

• IPC_SET – zmienia parametry segmentu pamięci wspólnej na parametry przekazane w strukturze wskazywanejprzez buf. Zmienione mogą zostać: właściciel i grupa (o ile wołający proces ma uid==0 lub taki sam, jakproces, który utworzył segment pamięci wspólnej) i prawa dostępu do segmentu.

• IPC_RMID – usuwa segment pamięci wspólnej z systemu.

• SHM_LOCK – zablokowanie w pamięci segmentu pamięci wspólnej (operacja może być wykonana wyłącznie przezużytkownika posiadającego euid==0);

• SHM_UNLOCK – odblokowanie segmentu.

Polecenia systemowe związane z pamięcią wspólną:

• ipcrm – usuwa segment pamięci wspólnej z systemu;

• ipcs -m – sprawdza status pamięci wspólnej w systemie.

Programowanie Współbieżne, INE 5242, 2010/2011 6-5

Page 66: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Korzystanie z pamięci wspólnej

Korzystanie z pamięci wspólnej

Zanim proces będzie mógł odczytać coś z pamięci wspólnej lub do niej zapisać, musi zażądać od systemu dołączeniasegmentu pamięci wspólnej do własnej przestrzeni adresowej (widząc jakby przez „okienko” swojej pamięci segmentpamięci wspólnej). Po zakończeniu korzystania z pamięci wspólnej, proces powinien odłączyć ją od swojej przestrzeniadresowej. Służą do tego odpowiednio funkcje shmat() i shmdt().

void *shmat(int shmid, const void *shmaddr, int shmflg);int shmdt(const void *shmaddr);

Funkcja shmat() zwraca adres przyłączonego segmentu. Adres ten zależy od użytych parametrów shmaddr i shmflg:

• Jeśli shmaddr==NULL (czyli (void*)0), to przydzielany jest pierwszy wolny adres znaleziony przez system;

• Jeśli shmaddr jest niezerowy, wówczas system podłącza segment pamięci wspólnej pod podanym adresem,chyba że została użyta także opcja SHM_RND, wówczas adres zostaje wyrównany w dół, do najbliższego adresupodzielnego przez SHMLBA.

• Użycie opcji SHM_RDONLY powoduje podłączenie pamięci w trybie wyłącznie do odczytu, w przeciwnym raziedostęp jest do czytania i pisania.

Funkcja shmdt() odłącza od przestrzeni adresowej procesu segment pamięci wspólnej wskazywany przez shmaddr.

Programowanie Współbieżne, INE 5242, 2010/2011 6-6

Page 67: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Pamięć wspólna widziana przez 2 procesy

Pamięć wspólna widziana przez 2 procesy

8CF1A000 RW-

20 bit 12 bit

0 0 1 A 7 3 F 0

8F345000 RWX

nr strony offset

tablica stron

8CF04000 R--81212000 R--8DD22000 R-X... ...8CF1A000 RW-8CF1B000 RW-

1A7

8C000000

pamiŒ� fizyczna

20 bit 12 bit

0 0 1 0 E 3 F 0

8F355000 R-X

nr strony offset

tablica stron

... ...

8DC10000 RW-8CFD4000 RW-8CFBB000 R--8CFA0000 R--

10E

proces 1

proces 2

8CF1A000

8CF1B000

8CF19000

3F0

8CF18000

Programowanie Współbieżne, INE 5242, 2010/2011 6-7

Page 68: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Pamięć wirtualna

Pamięć wirtualna

W rzeczywistości dostęp do pamięcijest trochę bardziej skomplikowany.(Deja Vu – to takie dziwne uczucie, ...)

• Tablica stron może zawieraćinformacje o stronach, których niema w pamięci fizycznej;

• w chwili dostępu do takiej stronygenerowany jest wyjątekpowodujący zachowanie kontekstuprocesu, ew. przeniesienie dokolejki procesów oczekujących nasprowadzenie strony z pamięciswap, oraz sprowadzenie strony, poczym wznowienie procesu tak,jakby nic się nie stało;

• Dodatkowo tablica zawiera licznikodwołań, automatyczniezmniejszany, a służący do szukaniastron, które mogą być wyrzuconedo pamięci swap.

20� b

�i

�t� 12 b

�i

�t�

1 A 7 3 F 0

s� e� g� m� e� n� t� i� n� r s� t� ro n� y o f

�f

�s� e� t�

t� a� b�l i

�c� a� s� t� ro n�

8CF04000 R--V

... ...8CF1A000 RW-V8CF1B000 RW-V

8CF1A000

8CF1B000

8CF19000

3F0

8C000000

p� a� m� i�Œ

�� f

�i�z� y c� z� n� a�

o b�s� z� a� r

p� ro c� e� s� u�

tablica s� eg� m� en� tów�

8F345000 RWXV

41212000 R---

8DD22000 R-XV... ...8CF1B000 R-XV

8FAA5000 RW-V8FAA6000 RW-V... ...8FAD1000 RW-V

0 0

k�od

d�

an� e

s� tos�

k�od

d�

an� e

s� tos�12

1

31

1

20

31

s� w� a� p�

p� l i�k� w� y m� i

�a� n� y

Programowanie Współbieżne, INE 5242, 2010/2011 6-8

Page 69: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna Pełny diagram stanów procesów

Pełny diagram stanów procesów

t�ry� b

� u� zy� t

�k.�

t�ry� b

� j

�a� d

�ra� .�

u� s�´p io ny� g� o t�o w� y�

u� s�´p io ny� / s� w� a� p g� o t

�o w� y� /

s� w� a� p

f�ork

�()

w� y� w� ła� s� zc� z.�

u� t�w� o rzo ny�

zo mb�ie�

s� w� a� p� -o� u� t�

s� w� a� p� -i�n�

ex� it()k

�ill()

p� rz� erw� an� ie

w� y w� łas! z� cz� .

p"o# w$ r% ó& t'

f

( . blo

kuj) ac

a

obud*

z� en� ie

Programowanie Współbieżne, INE 5242, 2010/2011 6-9

Page 70: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

6. Pamięć wspólna fork() jeszcze raz

fork() jeszcze raz

• Tworzenie nowego procesu funkcją fork() wymaga skopiowania do nowego procesu segmentu danych i stosu.

• Tworzenie nowych segmentów, alokowanie na nie stron pamięci i skopiowanie zawartości procesu macierzystegoto kosztowne operacje.

• Jeśli fork() jest wykonywany tylko po to, by chwilę później wykonać exec(), jest to niepotrzebnie wykonywanapraca i strata czasu.

Do poprawy efektywności wykonywania fork()+exec() służy „uproszczona” funkcja vfork(), która:

• Tworzy nowy proces, podobnie jak fork()

• Nie rozdziela segmentów danych i stosu tych procesów

• Wstrzymuje proces rodzica do momentu gdy proces potomny wykona którąś z funkcji exec() lub się zakończy.

• Proces potomny dziedziczy otwarte pliki podobnie jak w fork() – ich zamykanie jest niezależne od zamykaniaich w rodzicu.

Proces potomny tworzony przez vfork() ma bardzo ograniczone pole działania:

• Może pozamykać niepotrzebne deskryptory plików

• Nie może modyfikować żadnych zmiennych

• Nie może wołać żadnych własnych funkcji ani wykonać return

• Nie może wołać żadnych funkcji systemowych, z wyjątkiem funkcji z rodziny exec() i funkcji exit()

Programowanie Współbieżne, INE 5242, 2010/2011 6-10

Page 71: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Wątki

Istnieje kilka bibliotek do tworzenia wątków, wzajemnie niekompatybilnych. Najpopularniejsze to:

• Solaris threads

• POSIX Threads (pthreads)

Wątki zdefiniowane standardem POSIX są przenośne, system zapewnia wymuszanie opcji schedulera. Wątki systemuSolaris mogą być wstrzymywane i wznawiane, można w nich korzystać ze zoptymalizowanych operacji na semaforachi blokad czytania/pisania, a w systemach wieloprocesorowych mogą być uruchamiane równolegle.

Podstawowe cechy wątków:

• Tworzenie wątków jest szybsze i tańsze niż tworzenie nowego procesu

• Wszystkie wątki dzielą między sobą przestrzeń adresową procesu – dane i kod programu;

• Każdy wątek ma osobny stos i pewne atrybuty dotyczące wykonywania

• Wszystkie mają wspólny jeden numer procesu, rozróżniane są przez ID wątku uzyskiwany przy tworzeniunowego wątku

• Synchronizacja odbywa się przez specjalne funkcje związane z wątkami, operujące na semaforach, monitorachlub zmiennych warunkowych.

• Nie wszystkich funkcji systemowych można używać w wątkach w bezpieczny sposób („MT-Safe”).

Programowanie Współbieżne, INE 5242, 2010/2011 7-1

Page 72: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Podstawowe funkcje

• pthread create() (POSIX), thr create() (Solaris)

• pthread exit(), thr exit()

• pthread join(), thr join()

• pthread detach(), –

• pthread mutex init(), mutex init()pthread mutex trylock(), mutex trylock()pthread mutex lock(), mutex lock()pthread mutex unlock(), mutex unlock()pthread mutex destroy(), mutex destroy() – operacje na monitorach

• sem init(), sem wait(), sem trywait() i inne – operacje na semaforach

• pthread cond init(), pthread cond wait(), pthread cond timedwait(), pthread cond signal() i inne

• sched yield(), thr yield()

Programowanie Współbieżne, INE 5242, 2010/2011 7-2

Page 73: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Tworzenie wątków

#include <pthread.h>int pthread_create(pthread_t *new_thread_ID,

const pthread_attr_t *attr,void * (*start_func)(void *), void *arg);

#include <thread.h>int thr_create(void *stack_base, size_t stack_size,

void *(*start_func)(void *), void *arg, long flags,thread_t *new_thread_ID);

• Funkcja tworzy nowy wątek. Nowy wątek po utworzeniu zaczyna swoje życie na początku funkcji start_func.

• Wątek kończy się automatycznie po wyjściu z funkcji start_func, po wywołaniu pthread exit() lub thr exit(),odwołaniu wątku (pthread cancel()) lub zakończeniu przez exit() głównego procesu.

• pthread join() jest odpowiednikiem funkcji wait() – czeka na zakończenie określonego lub dowolnego wątku.

Tylko jeden z wątków może wykonać pthread join() podając ten sam wątek jako argument funkcji (pozostałekończone są natychmiast z błędem ESRCH).

Dalsze rozważania – na przykładzie wątków POSIX.

Programowanie Współbieżne, INE 5242, 2010/2011 7-3

Page 74: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Synchronizacja wątków

• Specjalne mechanizmy semaforów dostosowane do specyfiki programów wielowątkowych (Standard POSIX1003.1b)

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);int sem_wait(sem_t * sem);int sem_trywait(sem_t * sem);int sem_post(sem_t * sem);int sem_getvalue(sem_t * sem, int * sval);int sem_destroy(sem_t * sem);

• Mechanizm monitorów i zmiennych warunkowych (pthread mutex lock(), pthread cond wait() i inne)

– Monitor w najprostszej formie (bez zmiennej warunkowej) można traktować jak semafor binarny

– Z monitorem może być związana jedna lub kilka zmiennych warunkowych

– Zmienne warunkowe, inne (zwykłe) zmienne oraz sam monitor można zagregować we wspólny obiekt – np.w postaci klasy języka C++.

– Monitor służy do zapewnienia atomiczności operacji mogących mieć wpływ na zmienne z nim związane

Programowanie Współbieżne, INE 5242, 2010/2011 7-4

Page 75: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Zmienne warunkowe

• Zmienna warunkowa jest zawsze związana z monitorem (w celu uniknięcia wyścigu pomiędzy czekaniem nazajście warunku a sygnalizowaniem jego zajścia)

• Wątek może zostać wstrzymany do momentu spełnienia żądanego warunku (np. oczekiwanego wyniku porów-nania dwóch zmiennych itp.)

• Wykonanie pthread cond wait(), zawiesza wątek w oczekiwaniu na spełnienie warunku i automatycznie zwalniamonitor związany ze zmienną warunkową

• Wątek ponownie otrzymuje sterowanie po tym, gdy inny wątek wykona pthread cond broadcast() lub pth-read cond signal(): Wywołanie pthread cond signal() budzi dokładnie jeden wątek czekający na spełnieniewarunku, pthread cond signal() – wszystkie.

• W obudzonym wątku monitor jest ponownie zajęty, więc można kontynuować działanie w sekcji krytycznejdotyczącej zmiennej warunkowej, pamiętając także o konieczności wywołania pthread mutex unlock()

Przykład – ponownie problem pięciu filozofów:

• Za pomocą zmiennej warunkowej uzyskamy „bramkarza” nie wpuszczającego do jadalni więcej niż 3 filozofówjednocześnie

• Widelce (pałeczki) również można zaimplementować za pomocą zmiennych warunkowych, prościej jednakbędzie użyć samych monitorów (bez zmiennych) lub semaforów (binarnych)

Programowanie Współbieżne, INE 5242, 2010/2011 7-5

Page 76: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Monitory i zmienne warunkowe – przykład

/* ... zainicjowanie zmiennych warunkowych i monitorów ... */pthread_mutex_t bramka = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t miejsce = PTHREAD_COND_INITIALIZER;int ilu_je = 0;

void filozof(int nr) {while(1) {/* filozof medytuje */...

/* filozof się budzi i chce wejść do jadalni */pthread_mutex_lock(&bramka)while (ilu_je>=3) {pthread_cond_wait(&miejsce, &bramka); /* oczekiwanie na wolne miejsce */}/* ... wchodzi: */ilu_je++;pthread_mutex_unlock(&bramka);

... /* teraz można próbować wziąć widelce */

... /* oraz jeść */

/* koniec jedzenia i wyjście z jadalni */pthread_mutex_lock(&bramka);if (--ilu_je < 3)pthread_cond_broadcast(&miejsce); /* obudzenie filozofów czekających na wolne miejsce w jadalni */pthread_mutex_unlock(&bramka);}}

1

2

3

4

5

Programowanie Współbieżne, INE 5242, 2010/2011 7-6

Page 77: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Monitory i zmienne warunkowe – przykład (c.d.)

Sam sposób brania widelców można rozwiązać w „tradycyjny” sposób, traktując monitory jak semafory binarne:

/* inicjowanie mechanizmów -- gdzieś na początku */

pthread_mutex_t widelec[5]; /* tablica pięciu monitorów/semaforów binarnych */for (i=0; i<5; i++) {widelec[i]=PTHREAD_MUTEX_INITIALIZER;pthread_mutex_init(widelec+i);}

/* pobieranie widelców przez filozofa */

void filozof(int nr) {while(1) {...... /* wejście do jadalni */

pthread_mutex_lock(widelec+nr); /* zajmowanie widelców */pthread_mutex_lock(widelec+((nr+1)%5));/* filozof je */pthread_mutex_unlock(widelec+nr);pthread_mutex_unlock(widelec+((nr+1)%5));

... /* wyjście z jadalni */}}

Programowanie Współbieżne, INE 5242, 2010/2011 7-7

Page 78: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Monitory i zmienne warunkowe – przykład (c.d.)

Inny sposób pobierania widelców – z użyciem semaforów:

/* inicjowanie mechanizmów -- gdzieś na początku */

sem_t widelec[5]; /* tablica pięciu monitorów/semaforów binarnych */for (i=0; i<5; i++) {sem_init(widelec+i, 0, 1); /* pshared=0, początkowa wartość semafora = 1 */}

void filozof(int nr) {while(1) {...... /* wejście do jadalni */

sem_wait(widelec+nr); /* zajmowanie widelców */sem_wait(widelec+((nr+1)%5));/* filozof je */sem_post(widelec+nr);sem_post(widelec+((nr+1)%5));

... /* wyjście z jadalni */}}

/* gdzieś na końcu ... */for (i=0; i<5; i++) {sem_destroy(widelec+i);}

Programowanie Współbieżne, INE 5242, 2010/2011 7-8

Page 79: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Jeszcze jeden przykład problemu pięciu filozofów

• Monitory pozwalają w elegancki sposób rozwiązać problem wiążąc wszystkie wymagane mechanizmy w jednejstrukturze

• Zamiast implementować widelce w postaci semaforów wystarczy 5-elementowa tablica oznaczająca dostępnośćposzczególnych widelców

• Rolę semaforów mogą spełniać zmienne warunkowe – zmienna ok[i] oznacza, że filozof nr i może aktualniejeść (bo oba jego widelce leżą na stole i są wolne).

• Monitor służy do wzajemnego wykluczania operacji prowadzonych na tablicy widelców i zmiennych warunko-wych.

Algorytm postępowania filozofa:

• Zajmuje monitor, sprawdza, czy oba jego widelce są wolne.

• Jeśli nie są, zasypia na zmiennej warunkowej, czekając aż zostanie zasygnalizowany fakt, że oba są wolne.

Oczekiwanie na zmiennej warunkowej zwalnia monitor, dzięki czemu inni filozofowie są w stanie zwolnić widelcei zasygnalizować ten fakt.

• Jeśli (wreszcie) oba widelce są wolne, filozof zajmuje je (odnotowując w tablicy widelców) i zaczyna jeść.(zwalniając monitor)

• Po zakończeniu, ponownie zajmuje monitor i zwalnia widelce oraz sygnalizuje swoim sąsiadom, że (być może)mogą jeść (po czym zwalnia monitor i idzie medytować).

Programowanie Współbieżne, INE 5242, 2010/2011 7-9

Page 80: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Implementacja ostatniego rozwiązania

#define C_INIT PTHREAD_COND_INITIALIZERstruct {pthread_mutex_t mut;pthread_cond_t ok[5];int widelec[5];

} f={PTHREAD_MUTEX_INITIALIZER, {C_INIT, C_INIT, C_INIT, C_INIT, C_INIT}, {1,1,1,1,1} };

void filozof(int nr) {while(1) {pthread_mutex_lock(&f.mut); /* zajmowanie widelców - najpierw zajmij monitor*/while (f.widelec[nr]+f.widelec[(nr+1)%5] < 2) /* czy oba są wolne? */pthread_cond_wait(&f.ok[nr], &f.mut); /* nie są ==> czekaj */

f.widelec[nr]=0; /* zajmij oba naraz */f.widelec[(nr+1)%5]=0;pthread_mutex_unlock(&f.mut); /* oraz zwolnij monitor */

... /* filozof je */

pthread_mutex_lock(&f.mut); /* zwalnianie widelców - najpierw zajmij monitor*/f.widelec[nr]=1;f.widelec[(nr+1)%5]=1;

pthread_cond_signal(&f.[(nr-1+5)%5]; /* "szturchnij" lewego sąsiada */pthread_cond_signal(&f.[(nr+1)%5]; /* i prawego */pthread_mutex_unlock(&f.mut); /* oraz zwolnij monitor */

... /* idź medytować */}}

Programowanie Współbieżne, INE 5242, 2010/2011 7-10

Page 81: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

7. Wątki

Problemy z funkcjami systemowymi w wątkach

• Niektóre z funkcji systemowych operują na danych zapisywanych w statycznie przydzielanym obszarze pamięci

• Wywoływanie tych funkcji z różnych wątków powodowałoby nadpisywanie tego obszaru

Przykład: czytanie katalogu funkcją opendir() i readdir():

#include <stdio.h>#include <dirent.h>main(){

DIR *dirp;struct dirent *direntp;

dirp = opendir(".");while ( (direntp=readdir(dirp)) != NULL )

printf( "%s\n", direntp->d_name );closedir(dirp);return (0);

}

Większość funkcji takich jak readdir() posiada swoje odpowiedniki pozwalające na korzystanie z wątków, nazywanezwykle przez dodanie sufiksu _r (pochodzącego od słowa reentrant), np. readdir r().

Podobnie np. funkcje dotyczące tłumaczenia nazw DNS: gethostbyname() i gethostbyname r(), gethostbyname r(),gethostent r(), gethostbyaddr r() itp.

Programowanie Współbieżne, INE 5242, 2010/2011 7-11

Page 82: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

8. Różności Blokowanie dostępu do plików

Różności

Blokowanie dostępu do plików

• fcntl() z opcjami F_SETLK, F_SETLKW, F_GETLK.

– możliwa blokada zapisu lub blokada odczytu, całego pliku lub jego fragmentu.

• lockf ()

Podobna funkcjonalność, inne wywołanie. Poprzez F_TLOCK i F_TEST można sprawdzić możliwość uzyskaniablokady nie blokując procesu w celu jej uzyskania.

• BSD: flock()

Możliwość tworzenia „advisory lock” czyli blokad nie wymuszanych przez system blokowaniem procesu (procesmoże w międzyczasie zająć się innymi rzeczami.

Funkcja select()

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *errorfds, struct timeval *timeout);

void FD_ZERO(fd_set *fdset);void FD_SET(int fd, fd_set *fdset);void FD_CLR(int fd, fd_set *fdset);

int FD_ISSET(int fd, fd_set *fdset);

• Listy deskryptorów są upakowane w zmiennych readfds, writefds i errorfds, po 1 bit na deskryptor;

Programowanie Współbieżne, INE 5242, 2010/2011 8-1

Page 83: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

8. Różności Blokowanie dostępu do plików

• Do manipulowania tymi listami służą makra takie, jak FD_ZERO, zerujące listę, czy FD_SET, ustawiające bitodpowiedający podanemu deskryptorowi pliku, gniazda, strumienia FIFO itp.

• Jeśli lista jest pusta, można zamiast niej podać wskaźnik NULL;

• Struktura timeout określa maksymalny czas oczekiwania na dostępność określonych deskryptorów.

struct timeval {long tv_sec; /* sekundy */long tv_usec; /* mikrosekundy */};

Sposób interpretowania tego czasu:

– Powróć natychmiast, jeśli żaden deskryptor nie jest gotowy: struktura *timeout wypełniona zerami;

– Czekaj zadany czas: jeśli wartości w *timeout nie są obie równe zero;

– Czekaj w nieskończoność (aż któryś z deskryptorów będzie gotów): timeout == NULL.

Programowanie Współbieżne, INE 5242, 2010/2011 8-2

Page 84: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

8. Różności Programowanie w systemie UNIX – podsumowanie

Programowanie w systemie UNIX – podsumowanie

• Funkcje systemowe w przypadku błędów zwracają wartość −1, a informacja o przyczynie błędu zostaje umiesz-czona w zmiennej errno

• Standardowo funkcje we/wy są blokujące – jeśli żądanej czynności nie można wykonać od razu, proces jestusypiany, nie zajmując przez to czasu procesora w aktywnej pętli oczekiwania.

• Nieblokujące wejście/wyjście można uzyskać na różne sposoby:

– Ustawiając odpowiednie opcje deskryptora pliku (fcntl() – od tego momentu wszystkie operacje na de-skryptorze są nieblokujące).

– Poprzez użycie odpowiednich opcji w funkcji (np. IPC_NOWAIT w funkcjach IPC).

– Pozwalając na ewentualne blokowanie funkcji, ale przerwanie jej za pomocą sygnału (np. SIGALARM).

• Problem jednoczesnej obsługi wielu deskryptorów plików lepiej powierzyć funkcjom takim jak select() lubpoll() blokując proces w oczekiwaniu na jeden z wielu warunków, niż stosować nieblokujące we/wy.

Programowanie Współbieżne, INE 5242, 2010/2011 8-3

Page 85: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

Literatura

[1] Maurice J. Bach. Budowa systemu operacyjnego UNIX. Wydawnictwa Naukowo-Techniczne, 2 edition, 1995.oryginał: “The Design of the UNIX Operating System”, Prentice Hall, Inc., 1986.

[2] M. Ben-Ari. Podstawy programowania współbieżnego. Wydawnictwa Naukowo-Techniczne, 1 edition, 1989.oryginał: “Principles of Concurrent Programming”, Prentice-Hall International (UK) Ltd., 1983.

[3] Abraham Silberschats, James L. Peterson, and Peter B. Galvin. Podstawy systemów operacyjnych. WydawnictwaNaukowo-Techniczne, 2 edition, 1993. oryginał: “Operating System Concepts”, Addison-Wesley PublishingCompany, Inc., 1991.

[4] W. Richard Stevens. Programowanie zastosowań sieciowych w systemie Unix. Wydawnictwa Naukowo-Techniczne, 1 edition, 1995. oryginał: “UNIX Network Programming”, Prentice Hall, Inc., 1990.

Programowanie Współbieżne, INE 5242, 2010/2011 9-1

Page 86: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

Skorowidz

., 1-16/ , 1-5/etc/exports , 1-5/etc/fstab, 1-5/etc/mntab, 1-5/etc/passwd , 1-9/etc/shadow , 1-9/usr/include, 1-16/usr/include/signum.h, 2-9/usr/include/sys/signal.h, 2-9/usr/lib, 1-16/usr/lib/libc.a, 1-7/usr/lib/libsocket.so.2 , 1-7/usr/local/include, 1-16/usr/local/lib, 1-16exit(), 6-13

bg, 2-3

close(), 3-1

dup(), 3-6dup2 (), 3-6

exec(), 2-5, 2-7, 2-8, 3-7, 6-7, 6-13

execl(), 2-7execle(), 2-7execlp(), 2-7execv(), 2-7execve(), 2-7execvp(), 2-7exit(), 2-8, 2-10, 5-9, 6-7, 7-3

fcntl(), 2-7, 3-2, 3-3, 8-1, 8-5fg, 2-3flock(), 8-1fork(), 2-1, 2-4–2-6, 6-7, 6-13fprintf (), 3-1fread(), 6-10fseek(), 6-10ftok(), 4-9fwrite(), 6-10

gethostbyaddr r(), 7-11gethostbyname(), 7-11gethostbyname r(), 7-11gethostent r(), 7-11getpid(), 2-5getppid(), 2-5

9-2

Page 87: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

ioctl(), 3-2ipcrm, 4-4ipcs, 4-4

jobs, 2-3

kill, 2-3kill(), 2-5

ld.so, 1-8libc.so, 1-7, 1-8, 2-4libm.so, 1-8libnsl.so, 1-8libsocket.so, 1-8libX11.so, 1-8lockf (), 8-1

main(), 2-7mknod, 3-9mknod(), 3-9mmap(), 6-10msgctl(), 4-4msgget(), 4-3msgrcv(), 4-7msync(), 6-10munmap(), 6-10mutex destroy(), 7-2

mutex init(), 7-2mutex lock(), 7-2mutex trylock(), 7-2mutex unlock(), 7-2

nice, 2-1, 2-7

open(), 3-9opendir(), 7-11

pclose(), 3-8pipe(), 3-1poll(), 8-5popen(), 3-8printf (), 1-7ps, 2-3pthread cancel(), 7-3pthread cond broadcast(), 7-5pthread cond init(), 7-2pthread cond signal(), 7-2, 7-5pthread cond timedwait(), 7-2pthread cond wait(), 7-2, 7-4, 7-5pthread create(), 7-2pthread detach(), 7-2pthread exit(), 7-2, 7-3pthread join(), 7-2, 7-3pthread mutex destroy(), 7-2

Programowanie Współbieżne, INE 5242, 2010/2011 9-3

Page 88: Tomasz Surmaczdream.ict.pwr.wroc.pl › pw › pw-wyklad.pdf · 2010-11-22 · Programowanie Współbieżne Tomasz Surmacz tsurmacz@ict.pwr.wroc.pl Niniejsza publikacja stanowi materiały

pthread mutex init(), 7-2pthread mutex lock(), 7-2, 7-4pthread mutex trylock(), 7-2pthread mutex unlock(), 7-2, 7-5

read(), 3-1–3-3, 3-9readdir(), 7-11readdir r(), 7-11

sbrk(), 6-7sched yield(), 7-2select(), 3-3, 8-2–8-5sem init(), 7-2sem trywait(), 7-2sem wait(), 7-2semctl(), 5-8semget(), 5-7semop(), 5-12setpgrp(), 2-10sh, 3-8shmat(), 6-6, 6-7shmctl(), 6-5, 6-8shmdt(), 6-6, 6-8shmget(), 6-4, 6-7sigaction(), 4-7sighold(), 2-9sigignore(), 2-9

signal(), 2-9, 5-12sigpause(), 2-9sigrelse(), 2-9sigset(), 2-9

thr create(), 7-2thr exit(), 7-2, 7-3thr join(), 7-2thr yield(), 7-2

umask, 2-7unlink(), 3-9

vfork(), 6-13

wait(), 2-5, 2-10, 3-8, 7-3write(), 3-1, 3-2, 3-9

Zajmij (), 5-3, 5-4Zwolnij (), 5-3, 5-4

Programowanie Współbieżne, INE 5242, 2010/2011 9-4