Jeden semafor 2 procesy

0

Witam. Mam pewien problem ze zrozumieniem semaforów.
Jeżeli mam jedną zmienną współdzieloną int c = 100, semafor sem = 0 i dwa współbieżne procesy o kodach:

proces1 proces2
c++; c++;
P(sem) V(sem)
c1 = c; c2 = c
c = c1 - 2; P(sem)
V(sem) c = c2 + 1
V(sem)

To proces 1 się zablokuje bo próbuje zamknąć semafor o wartości 0. Ale teraz semafor podnosi proces drugi. Czyli jaka sekcja krytyczna się wykona? Ta z procesu pierwszego bo teraz proces pierwszy może zamknąć semafor bo otworzył go proces 2. Jak to jest?

0

Obie będą się wykonywać jednocześnie bo jest to źle zaprojektowane. Semafor powinien mieć wartość 1 a oba procesy powinny próbować go zamknąć. W ten sposób tylko jednemu się uda a drugi będzie musiał czekać aż tamtem pierwszy podniesie semafor przy wyjściu z sekcji krytycznej ;]

0

No też doszedłem do tego wniosku ale to jest zadanie z kolokwium i średnio wiem jak to rozegrać.

0

Nie bardzo rozumiem. Podany kod jest błędny od samego początku, bo juz operacja c++ wykonywana przez dwa wątki poza sekcja krytyczną spowoduje nieokreślony wynik. Może chodziło właśnie o to żeby opisać gdzie tu są błędy? ;]

0

Chodzi o to żeby określić jaką wartość może osiągnąć zmienna C a jakiej nigdy nie osiągnie: 3,4,5,6,7
Wszystkie operacje są atomowe. Może specjalnie to jest tak zrobione żeby utrudnić dojście do odpowiedzi :p

0
Shalom napisał(a)

operacja c++ wykonywana przez dwa wątki poza sekcja krytyczną spowoduje nieokreślony wynik
inkrementacja zmiennej o rozmiarze mieszczącym się w rejestrze jest faktycznie operacją atomową.

JJ napisał(a)

Chodzi o to żeby określić jaką wartość może osiągnąć zmienna C a jakiej nigdy nie osiągnie
w którym momencie? w trakcie którejkolwiek zmiany, na wyjściu procesu, który skończy się wcześniej, czy na wyjściu procesu, który skończy się później?

zapomniałeś dodać, że c=100 binarnie, czyli 4 dziesiętnie.
według mnie po zakończeniu obu procesów c może przyjąć wartości 3, 4, 5, 6 lub 7.

0

Ustalmy że C ma na początku wartość 5. Reszta pozostaje bez zmian. Jaką wartość może osiągnąć C a jakiej nigdy nie osiągnie po zakończeniu przetwarzania przez oba procesy. Każda linia jest jest operacja atomową i mamy semafor ogólny zliczający.

0

A czy ja dobrze w ogóle rozumuje.
Mamy na początku wartość 5. Jeżeli mamy dwa razy inkrementację to wartość będzie 7.
Proces 1 utknie w momencie opuszczania semafora. Proces 2 podniesie semafor i 2 procesy zaczną wykonywać swoje sekcje krytyczne. Pod c1 zostanie podstawione 7 i pod c2 zostanie podstawione 7. Proces 2 utknie w trakcie opuszczania semafora i proces 1 obliczy nową wartość c = 5 i podniesie semafor. Wtedy proces 2 opuści semafor i obliczy wartość c = 8 i podniesie semafor? Tak?

0

Coś nie tak, ale nie mam czasu sprawdzić - według mnie kod nie może wykonać się tak, żeby na wyjściu było 8.
To, że oba wątki/procesy wykonują się współbieżnie, nie znaczy, że proces A nie wykona się w całości przed procesem B. Tak naprawdę całość może wykonać się w dowolnej kombinacji linijek (za wyjątkiem sekcji krytycznych - ale i to nie zawsze, bo drugi proces może wbić się do sekcji pierwszego procesu).

0

A ma ktoś sposób jak by to ugryźć?

0

sprawdź co by musiało się stać, żeby wynikiem była dana liczba, a potem sprawdź, czy kod faktycznie może się tak wykonać.
np. dla 7 musi się wykonać (a = proces 1, b = proces 2, a4 - czwarta linijka (licząc od 1) procesu 1) a1, b1, b3, b5 lub b1, a1, b3, b5.
wszystkie pozostałe operacje muszą dać wykonać się w kolejności takiej, aby nie miały wpływu na wynik. więc tak:
a1, b1 - da się.
b2, b3 - da się.
a2, a3, a4, a5 - da się.
b4, b5, b6 - da się.
wszystko da się, ergo w pewnych warunkach na zakończeniu obu procesów c może osiągnąć wartość 7.

dla 8 - po a1=5, po b1=6, po b5=7, więcej operacji inkrementacji nie ma, więc 8 i wyższych wartości nie da się osiągnąć.
dla 2 - po a4=2, ale wcześniej mamy przynajmniej jedną obowiązkową inkrementację (a1 lub b1), więc 2 nie da się osiągnąć, to samo tyczy niższych wartości.
dla 3 - potrzebujemy a1 lub b1 (ale nie oba) i a4; skoro przed a4 MUSI się wykonać a1, to b1 odpada (wynik operacji b1 musi być pomijalny), a więc: a1, a2, a3 (to zapewnia pomijalność b1 i dalszych b*), b1, b2, b3, b4, b5, a4, a5. muteks nie przeszkadza na żadnym etapie.
dla innych kombinacji pomyśl sam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1