Void *funcT1(void *arg)
{
srand(time(NULL));
int q = -5 + rand() % 11;
q=q*7;
cout<<" q= "<<q<<'\n';
if (q>v)
{
q=1;
}
else
{
q=0;
}
cout<<"T1 generate q: "<<q<<'\n';
Mon.InputTemp(q);
Mon.SignalTemp();
}
Void *funcT2(void *arg)
{
Mon.WaitTemp();
int q = Mon.OutputTemp();
cout<<"T2 recieve q: "<<q<<'\n';
}
int main(int argc, char *argv[])
{
Mon.MonitorInit();
pthread_t T1,T2;
pthread_create(&T1,NULL,funcT1,NULL);
pthread_create(&T2,NULL,funcT2,NULL);
pthread_join(T1,NULL);
pthread_join(T2,NULL);
cin.get();
return 0; }
Розглянути приклад 6.2 з лекції 6. Переробити програму таким чином, щоб масив а ініціалізувався випадковими числами в діапазоні [1;30], а потоки Т0 та Т1, щоб рахували кількість елементів, значення яких дорівнює С (де С – це номер варіанту студента).
Алгоритм роботи кожного потоку
Тгол |
Т0 |
Т1 |
1) Ініціалізація монітору. 2) Ініціалізація масиву а 3) Створення потоків. 4) Приєднання потоків. |
Для і = 0, …, N/2: 1) Перевірка а[i]. 2) Якщо a[i] == с: ---------- КС ------------------- 2.1) Перевіка Count: 2.2) Якщо Count = N/2: 2.2.1) завершити програму 2.3) Якщо Count != N/2: 2.2.1) Count ++ ------------------------------------ |
Для і = (N-1)/2+1, …, N-1:
Дії такі ж як і для потоку Т0 |
Лістинг програми
#include <pthread.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int N;
int *a;
const int c=4;
struct Monitor
{
private:
int Count;
pthread_mutex_t mutex;
public:
void MonitorInit()
{
pthread_mutex_init(&mutex,NULL);
Count = 0;
}
int TestAndIncCount()
{
pthread_mutex_lock(&mutex);
if (Count == N/2)
{
pthread_mutex_unlock(&mutex);
return 1;
}
else
{
Count++;
pthread_mutex_unlock(&mutex);
return 0;
}
}
int OutputCount()
{
return Count;
}
};
Monitor Mon;
void *funcT (void *arg)
{
int NumT = (int)arg;
int i;
for (i=NumT*((N-1)/2+1); i<=(NumT+1)*(N-1)/2; i++)
{
if (a[i] == c)
{
if (Mon.TestAndIncCount() == 1)
{
break;
}
}
}
}
int main (int argc, char *argv[])
{
Mon.MonitorInit();
N = atoi (argv[1]);
a = new int[N];
int i, RealNumZero = 0;
for (i=0; i<=N-1; i++)
{
srand(time(NULL)+i);
a[i] = 1 + rand() % 30;
if (a[i] == c) {RealNumZero++;}
cout<<a[i]<<'\t';
}
cout<<'\n';
cout<<"RealNumZero = "<<RealNumZero<<'\n';
cout<<"N = "<<N<<'\n';
pthread_t T[2];
for (i=0; i<=1; i++)
{
pthread_create(&T[i],NULL,funcT,(void *) i);
}
for (i=0; i<=1; i++)
{
pthread_join(T[i],NULL);
}
cout<<"Count = "<<Mon.OutputCount();
cin.get();
return 0;
}
Розглянути приклад 7.1 лекції 7. Запустити програму з різною кількістю потоків. Відповісти на питання: коли потоки починають отримувати доступ до ресурсу у відповідності із заданою схемою з пріоритетами?
Алгоритм роботи кожного потоку
Тгол |
Т0, ..., ТК-1 |
1) Введення К 2) Ініціалізацію мютексу виведення. 3) Ініціалізація монітору. 4) Створення потоків. 5) Приєднання потоків. |
1) Отримати номер потоку NumT. 2) Повідомлення “Thread Id start.” 3) Генерувати випадкове p. 4) request(NumT,p). 5) Повідомлення „Thread Id priority = Р”. 6) release(). 7) Повідомлення „Thread Id finish.” |
Лістинг програми
#include <pthread.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int K;
pthread_mutex_t mutexOut;
struct Monitor
{
private:
int FConsole;
pthread_mutex_t mutex;
pthread_cond_t *cond;
int q_count;
struct queue {int id; int priority;};
queue *Queue;
public:
void monitorInit()
{
FConsole = 0;
q_count = 0;
pthread_mutex_init(&mutex,NULL);
cond = new pthread_cond_t [K];
Queue = new queue [K];
int i = 0;
for (i=0; i<=K-1; i++)
{
pthread_cond_init(&cond[i],NULL);
Queue[i].id = 0;
Queue[i].priority = 0;
}
}
void request(int id, int priority)
{
pthread_mutex_lock(&mutex);
if (FConsole == 1)
{
//Place find
int i = 0;
while (Queue[i].priority>priority && i<=q_count-1)
{
i++;
}
int I = i;
//Shift right
for (i=q_count; i>=I+1; i--)
{
Queue[i].id = Queue[i-1].id;
Queue[i].priority = Queue[i-1].priority;
}
//Insert
Queue[i].id = id;
Queue[i].priority = priority;
q_count++;
pthread_cond_wait(&cond[id],&mutex);
}
FConsole = 1;
pthread_mutex_unlock(&mutex);
}
void release()
{
pthread_mutex_lock(&mutex);
if (q_count > 0)
{
int idSignal = Queue[0].id;
int i;
for (i = 0; i<=q_count-2; i++)
{
Queue[i].id = Queue[i+1].id;
Queue[i].priority = Queue[i+1].priority;
}
q_count--;
pthread_cond_signal(&cond[idSignal]);
}
FConsole = 0;
pthread_mutex_unlock(&mutex);
}
};
Monitor Mon;
void *funcT(void *arg)
{int NumT = (int) arg;
pthread_mutex_lock(&mutexOut);
cout<<"Thread "<<NumT<<" start.\n";
pthread_mutex_unlock(&mutexOut);
srand(time(NULL)+NumT);
int p = 1+rand()%5;
Mon.request(NumT,p);
pthread_mutex_lock(&mutexOut);
cout<<"Thread "<<NumT<<" priority = "<<p<<'\n';
pthread_mutex_unlock(&mutexOut);
Mon.release();
pthread_mutex_lock(&mutexOut);
cout<<"Thread "<<NumT<<" finish.\n";
pthread_mutex_unlock(&mutexOut);
}
int main(int argc, char *argv[])
{
cout<<"Input K: ";
cin>>K;
pthread_t *T;
pthread_mutex_init(&mutexOut,NULL);
Mon.monitorInit();
T = new pthread_t[K];
int i;
for (i=0; i<=K-1; i++)
{
pthread_create(&T[i],NULL,funcT,(void *) i);
}
for (i=0; i<=K-1; i++)
{
pthread_join(T[i],NULL);
}
cin>>i;
return 0;
6. Розглянути приклад 8.1 лекції 8. Переробити програму таким чином, щоб реалізовувався граф передування з таблиці 4.1 (за варіантом).
Тгол |
T1 |
T2 |
T3 |
T4 |
T5 |
1)Ініціалізація моніторів. 2) Створення потоків. 3) Приєднання потоків. 4) Виведення q1. |
1) x=х*5 2) sign T3 (V(S1))
|
1) y=у+2 2) sign T3 (V(S2)) 3) sign T4 (V(S2)) |
1) wait T1 (P(S1)) 2) wait T2 (P(S2)) 3) х=х+2 4) signal T5 (V(S3)) |
1) wait T2 (P(S2)) 3) у=у-3 4) signal T5 (V(S3)) |
1) wait T3 (P(S3)) 2) wait T4 (P(S3)) 3) у=х*у |
Лістинг програми
#include <iostream>
#include <pthread.h>
using namespace std;
int x = 1, y = 1;
int min(int a, int b)
{
if (a>b) {a = b;}
return a;
}
struct Semaphore
{
private:
int na,np, nv;
pthread_mutex_t mutex;
pthread_cond_t cond;
public:
void MonitorInit()
{
na = np = nv = 0;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
}
void Psem()
{
pthread_mutex_lock(&mutex);
na++;
while (np == min(na,nv))
{
pthread_cond_wait(&cond, &mutex);
}
np++;
pthread_mutex_unlock(&mutex);
}
void Vsem()
{
pthread_mutex_lock(&mutex);
nv++;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
};
Semaphore S1, S2, S3;