Synchronisatiefouten

Download Report

Transcript Synchronisatiefouten

Synchronisatiefouten

Rendez-vous

Draad 1 Draad 2 Rendez-vous Draad 1 Draad 2 release acquire

Semafoor s1; Semafoor s2; } Draad1: { // Doe werk s2.release(); s1.acquire(); // Doe werk } Draad2: { // Doe werk s1.release(); s2.acquire(); // Doe werk Draad 1 Draad 2 release acquire s2 s1 release acquire

1,2 2,1 3,1 3,2 1,3 2,3 Draad 1 Draad 2 Draad 3 release acquire release acquire release acquire

Semafoor mutex = 1; Condition barrier; int count = 0; } draad: { // doe werk mutex.acquire(); count++; mutex.release(); if (count < n) barrier.wait(); else barrier.signal(); // doe werk Draad 1 Draad 2 Draad n … Barrier

Semafoor mutex = 1; Condition barrier; int count = 0; } draad: { // doe werk mutex.acquire(); count++; if (count < n) barrier.wait(); else barrier.signal(); mutex.release(); // doe werk Draad 1 Draad 2 Draad n … Barrier

Semafoor mutex = 1; Condition barrier; int count = 0; } draad: { // doe werk mutex.acquire(); count++; if (count < n) barrier.wait(mutex); else barrier.signal(); mutex.release(); // doe werk Draad 1 Draad 2 Draad n … Barrier

Semafoor mutex = 1; Condition barrier; int count = 0; } draad: { // doe werk mutex.acquire(); count++; if (count < n) { barrier.wait(mutex); barrier.signal(); } else barrier.signal(); mutex.release(); // doe werk Draad 1 Draad 2 Draad n Barrier

Semafoor mutex = 1; Condition barrier; int count = 0; draad: { // doe werk mutex.acquire(); count++; if (count < n) { barrier.wait(mutex); barrier.signal(); } } else { barrier.signal(); count = 0; mutex.release(); // doe werk } mutex.acquire(); count++; if (count < n) { barrier.wait(mutex); barrier.signal(); } else { barrier.signal(); count = 0; } mutex.release(); // doe werk Draad 1 Draad 2 Draad n Barrier

Semafoor mutex = 1; Condition barrier; int count = 0; draad: { // doe werk mutex.acquire(); count++; if (count < n) { barrier.wait(mutex); } else { barrier.signalall(); count = 0; } mutex.release(); // doe werk } mutex.acquire(); count++; if (count < n) { barrier.wait(mutex); } else { barrier.signalall(); count = 0; } mutex.release(); // doe werk Draad 1 Draad 2 Draad n Barrier

Semafoor mutex = 1; Semafoor filo[5] = [0,0,0,0,0]; State [hungry, eating, thinking] state[5] = [thinking, thinking, thinking, thinking, thinking]; filosoof(i): while (1) { get_forks(i); sleep(t1); // eat put_forks(i); sleep(t2); // think } get_forks(i): mutex.acquire(); state[i] = hungry; test(i); mutex.release(); filo[i].acquire(); put_forks(i): mutex.acquire(); state[i] = thinking; test(right(i)); test(left(i)); mutex.release(); test(i): if (state[i] == hungry and state[left(i)] != eating and state[right(i)] != eating) { state[i] = eating; filo[i].release(); }

Vaak gemaakte fouten

• Data races • Deadlock • • Geen lus in draad Niet blokkeren indien vereist • Volgorde van events niet respecteren • Sequentialiseren

De Brug

N togen voor bestelling klanten en 1 frietkok. Lading frietjes = M porties. Toog vraagt nieuwe frietjes aan kok indien maar 2 porties meer zijn. Frietkok bezorgt frietjes in volgorde van aanvragen.

mailbox bestellingen; semafoor m[N] = [1,…,1]; int porties[N] = [M,…,M]; condition meerfrietjes[N]; } Toog(int n) { while (1) { m[n].acquire(); if (porties[n] == 0) meerfrietjes[m].wait(m[n]); porties[n]--; if (porties[n] == 2) bestellingen.send(n); m[n].release(); } } Frietkok { int n; while (1) { bestellingen.receive(&n); m[n].acquire(); porties[n] += M; m[n].release(); meerfrietjes[n].signal()l; }

Alternatieve oplossing 1

Mutex wachtrij_mutex; Cond_var niet_lege_wachtrij; dist togen = new ArrayList<>(); } Toog(int n) { lock(wachtrij_mutex); togen.add(n); broadcast(niet_lege_wachtrij, wachtrij_mutex); unlock(wachtrij_mutex); } Frietkok { lock(wachtrij_mutex); if (togen.size() == 0) { wait(niet_lege_wachtrij, wachtrij_mutex); } serveer(togen.get(0)); unlock(wachtrij_mutex);

Alternatieve oplossing 2

Monitor { int porties[N] = {M}; Queue wachtrij = 0; Condition kok, klaar[N]; } Toog(int n) { if (porties[n] < 1) klaar[n].wait(); porties[n]--; if (porties[n] == 2) { wachtrij.enqueue(n); kok.signal(); } } Frietkok { if (wachtrij.is_empty()) kok.wait(); int toog = wachtrij.dequeue(); porties[n] += M; klaar[toog].signal(); }

Alternatieve oplossing 3

Mutex mutex = new Mutex(); Condition kok new Condition(); Volatile int aantalPorties = M; } Toog(int n) { mutex.acquire(); if (aantalPorties > 0) { aantalPorties--; if (aantalPorties == 2) kok.signal(); } mutex.release(); } Frietkok { while (true) { while (aantalPorties > 2) kok.wait(); bakfrietjes(); mutex.acquire(); aantalPorties += M; mutex.release(); }