09 noiembrie 2010
03 noiembrie 2010
Modelul "Replicated Workers" si rezolvarea problemei reginelor
2. Pentru gestiunea sarcinilor se foloseste o structura de date abstracta numita Work Pool (WP). Un WP reprezinta o colectie de descriptori, fiecare caracterizand un task ce poate fi executat de catre oricare dintre muncitori.
3. Cand un muncitor devine inactiv, preia o noua sarcina din WP si executa calculele necesare. In timpul acestei executii un muncitor poate genera noi sarcini ce se adauga in WP. Sarcinile trebuie concepute astfel incat sa poata fi rezolvate de catre oricare dintre munictori.
4. Activitatea comuna (paralela) a muncitorilor se considera terminata atunci cand:
a. Toti muncitorii sunt inactivi (cer un nou task).
b. WP este gol (nu mai exista taskuri de executat). (Observam ca WP poate fi gol insa cativa muncitori activi. In acest caz nu putem fi siguri de terminare activitatii, pentru ca pot fi generate noi taskuri).
Primitivele de lucru cu WP sunt:
* getWork - pentru primirea unei sarcini din WP si
* putWork - pentru plasarea unei sarcini in WP
Rezolvarea: http://dl.dropbox.com/u/24465060/Replicated%20Workers.zip
01 noiembrie 2010
Impartirea unui for pe mai multe thread-uri
#include "omp.h"
int main() {
int i, n, tid;
float a[10], b[10], sum;
/* initializari */
n = 10;
for (i=0; i < n; i++)
a[i] = b[i] = i * 1.0;
sum = 0.0;
omp_set_num_threads(3); // setam 3 thread-uri
// la final, fiecare thread va aduna la variabila sum, valoarea calculata
#pragma omp parallel for reduction(+:sum) private(tid)
for (i=0; i < n; i++)
{
sum = sum + (a[i] * b[i]);
tid = omp_get_thread_num();
printf("Sum = %f, from thread %d\n",sum, tid);
}
printf(" Sum = %f\n",sum); // suma finala
return 0;
}
Problema producator-consumator
Fie un vector numit buffer la care in permanenta au acces 2 entitati: un producator, care adauga elemente ori de cate ori bufferul permite acest lucru (nu se depaseste capacitatea), si un consumator care extrage elemente ori de cate ori este posibil (pana cand se ajunge la vectorul vid). In Java, simularea poate arata in felul urmator:
// clasa care creeaza cele 2 thread-uri si le porneste
import java.util.*;
class ProdCons {
public static void main (String args[]) {
Vector buffer;
int nmax;
nmax = 10;
buffer = new Vector(nmax);
for(int i=0; i<=nmax-1; i++)
buffer.addElement(i);
Prod prod = new Prod(buffer, nmax);
Cons cons = new Cons(buffer);
cons.start();
prod.start();
}
// producatorul
import java.util.*;
public class Prod extends Thread {
Vector buffer;
int cap;
int i;
public Prod (Vector buffer, int cap) {
this.cap = cap;
this.buffer = buffer;
i = 11;
}
public void run() {
while (true) {
try {
if (buffer.size()<=cap-1) {
System.out.println("Produc "+i);
buffer.addElement(i);
i++;
synchronized (buffer) {
buffer.notify(); //wakes up the first thread that called wait( ) on the same object.
}
}
synchronized (buffer) {
buffer.wait(); // tells the calling thread to give up the monitor and go to sleep until some other
//thread enters the same monitor and calls notify( ).
}
sleep(4);
}
catch (Exception e) {};
}
}
}
}
// consumatorul
import java.util.*;
public class Cons extends Thread {
Vector buffer;
public Cons (Vector buffer) {
this.buffer = buffer;
}
public void run() {
while(true) {
try {
if(buffer.size()>=1) {
System.out.println("Consum "+buffer.firstElement());
buffer.remove(buffer.firstElement());
System.out.println("buffer.size in Cons="+buffer.size());
synchronized (buffer) {
buffer.notify();
}
}
synchronized (buffer) {
buffer.wait();
}
sleep(10);
}
catch(Exception e) {};
}
}
}
Un alt exemplu mai puteti gasi AICI .