fork download
  1. /*
  2.   *shial
  3.   *g++ -Wall -lpthread -o threads.exe thread.cpp -lncurses
  4.   */
  5.  
  6. #include <iostream>
  7. #include <deque>
  8. #include <stdlib.h>
  9. #include <time.h>
  10. #include "ncurses/ncurses.h"
  11. extern "C"
  12. {
  13. #include <pthread.h>
  14. #include <semaphore.h>
  15. #include <unistd.h>
  16. }
  17.  
  18. using namespace std;
  19.  
  20. int kolumny = 0;
  21. int rzedy = 0;
  22.  
  23. unsigned _licznik[30];
  24. bool _cout[30];
  25.  
  26. //printw("tekst") - Wyswietla napis na ekranie. W tym wypadku efekt jest podobny jak w cout
  27. //funkcja getch() znana z conio.h, oczekuje ona na wcisniecie przycisku i ew. go zwraca
  28.  
  29. /*
  30.  * Kod Studenta.
  31.  * Student jest rekordem
  32.  * Posiadajacym int'a do którego wrzucamy 4 profesorów
  33.  */
  34. int UtworzStudenta()
  35. {
  36. int StudentRekord=0;
  37. for(int i=0;i<4;i++)
  38. StudentRekord|=(1<<(rand()%10)); // dodajemy losowych prowadzacych;
  39. return StudentRekord;
  40. }
  41.  
  42. void Legenda()
  43. {
  44. move( 22, 0 );
  45. start_color();
  46. init_pair(7, COLOR_CYAN, COLOR_BLACK);
  47. attron(COLOR_PAIR(7));
  48. printw( "LEGENDA: " );
  49. attroff(COLOR_PAIR(7));
  50. init_pair(5, COLOR_GREEN, COLOR_BLACK);
  51. attron(COLOR_PAIR(5));
  52. printw( "WPIS, " );
  53. attroff(COLOR_PAIR(5));
  54. init_pair(1, COLOR_YELLOW, COLOR_BLACK);
  55. attron(COLOR_PAIR(1));
  56. printw( "QUEUE3, " );
  57. attroff(COLOR_PAIR(1));
  58. init_pair(2, COLOR_RED, COLOR_BLACK);
  59. attron(COLOR_PAIR(2));
  60. printw( "QUEUE2, " );
  61. attroff(COLOR_PAIR(2));
  62. init_pair(3, COLOR_WHITE, COLOR_BLACK);
  63. attron(COLOR_PAIR(3));
  64. printw( "QUEUE1, " );
  65. attroff(COLOR_PAIR(3));
  66. init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
  67. attron(COLOR_PAIR(4));
  68. printw( "QUEUE0, " );
  69. attroff(COLOR_PAIR(4));
  70. refresh();
  71. }
  72.  
  73. void WypiszNaEkran(string tekst)
  74. {
  75. move( 0, 0 );
  76. clrtoeol();
  77. printw( tekst.c_str() );
  78. refresh();
  79. }
  80.  
  81. void WypiszNaEkran(string tekst,int i, bool b)
  82. {
  83. start_color();
  84. init_pair(5, COLOR_GREEN, COLOR_BLACK);
  85. attron(COLOR_PAIR(5));
  86. if(_licznik[i]>75)
  87. {
  88. _licznik[i]=0;
  89. move( 2*i, _licznik[i] );
  90. clrtoeol();
  91. }
  92. move( 2*i, _licznik[i] );
  93. _licznik[i]++;
  94. //clrtoeol();
  95. printw( "%c",232 );//tekst.c_str()
  96. attroff(COLOR_PAIR(5));
  97. refresh();
  98. }
  99. void WypiszNaEkran(string tekst,int i, int color)
  100. {
  101. int farba=0;
  102. start_color();
  103. switch(color)
  104. {
  105. case 1:
  106. farba =1;
  107. init_pair(1, COLOR_YELLOW, COLOR_BLACK);
  108. break;
  109. case 2:
  110. farba =2;
  111. init_pair(2, COLOR_RED, COLOR_BLACK);
  112. break;
  113. case 3:
  114. farba =3;
  115. init_pair(3, COLOR_WHITE, COLOR_BLACK);
  116. break;
  117. case 4:
  118. farba =4;
  119. init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
  120. break;
  121. default:
  122. farba =0;
  123. init_pair(0, COLOR_CYAN, COLOR_BLACK);
  124. break;
  125. }
  126. attron(COLOR_PAIR(farba));
  127. if(_licznik[i]>75)
  128. {
  129. _licznik[i]=0;
  130. move( 2*i, _licznik[i] );
  131. clrtoeol();
  132. }
  133. move( 2*i, _licznik[i] );
  134. _licznik[i]++;
  135. printw( "%c",232 );//tekst.c_str()
  136. attroff(COLOR_PAIR(farba));
  137. refresh();
  138. }
  139.  
  140. deque < int > kolejka0;
  141. deque < int > kolejka1;
  142. deque < int > kolejka2;
  143. deque < int > kolejka3;
  144.  
  145. pthread_mutex_t mutex_iostream = PTHREAD_MUTEX_INITIALIZER;
  146. pthread_mutex_t mutex0 = PTHREAD_MUTEX_INITIALIZER;
  147. pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
  148. pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
  149. pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
  150. //pthread_cond_t space_available = PTHREAD_COND_INITIALIZER;
  151.  
  152.  
  153. void * Profesor(void * arg);
  154. void * Portier(void * arg);
  155. void * Wyjscie(void * arg);
  156.  
  157. pthread_t *profesorTab=NULL;
  158. pthread_t *portierTab=NULL;
  159. pthread_t wyjscieExit;
  160.  
  161. int main()
  162. {
  163. initscr();// ktora musimy zawsze użyc przed rozpoczeciem pracy z biblioteka New Curses.
  164. getmaxyx( stdscr, rzedy, kolumny ); //Pobieranie wartości okna do zmiennych
  165.  
  166. for(int i=0; i<30; i++)
  167. {
  168. _licznik[i]=0;
  169. _cout[i]=false;
  170. }
  171. srand (time(NULL));
  172. //ustawiamy atrybuty na domyslna wartosc
  173. pthread_attr_t attr;
  174. pthread_attr_init(&attr);
  175. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  176.  
  177. pthread_mutex_init(&mutex_iostream, NULL);
  178. pthread_mutex_init(&mutex0, NULL);
  179. pthread_mutex_init(&mutex1, NULL);
  180. pthread_mutex_init(&mutex2, NULL);
  181. pthread_mutex_init(&mutex3, NULL);
  182.  
  183. pthread_mutex_lock(&mutex_iostream);
  184. Legenda();
  185. pthread_mutex_unlock(&mutex_iostream);
  186.  
  187. //pthread_create( &wyjscieExit, NULL, &Wyjscie, NULL);
  188.  
  189. portierTab=new pthread_t[5];
  190. for(int i=0; i<5; i++)
  191. {
  192. int _i = i+15;
  193. pthread_create( &portierTab[i], NULL, &Portier, &_i);
  194. }
  195. //inicjalizujemy 10 watkow studentow
  196. profesorTab=new pthread_t[10];
  197. for(int i=0; i<10; i++)
  198. {
  199. pthread_create( &profesorTab[i], NULL, &Profesor, &i);
  200. }
  201. pthread_mutex_lock(&mutex_iostream);
  202. WypiszNaEkran("Dzialanie watkow");
  203. pthread_mutex_unlock(&mutex_iostream);
  204. //Rozpoczynamy dzialanie watkow
  205.  
  206. //pthread_join( wyjscieExit, NULL);
  207.  
  208. for(int i=0; i<5; i++)
  209. {
  210. pthread_join( portierTab[i], NULL);
  211. }
  212. for(int i=0; i<10; i++)
  213. {
  214. pthread_join( profesorTab[i], NULL);
  215. }
  216.  
  217. pthread_attr_destroy(&attr);
  218. pthread_mutex_destroy(&mutex_iostream);
  219. pthread_mutex_destroy(&mutex0);
  220. pthread_mutex_destroy(&mutex1);
  221. pthread_mutex_destroy(&mutex2);
  222. pthread_mutex_destroy(&mutex3);
  223. delete [] profesorTab;
  224. pthread_exit(NULL);
  225. pthread_mutex_lock(&mutex_iostream);
  226. WypiszNaEkran("Koniec Programu");
  227. pthread_mutex_unlock(&mutex_iostream);
  228. endwin();// Konczy prace biblioteki New Curses.
  229. return 0;
  230. }
  231.  
  232. /*
  233.  * Kod Profesora.
  234.  *
  235.  * Profesor przeszukuje kolejki w kolejności 3,2,1
  236.  * w poszukiwaniu studenta który potrzebuje jego podpisu.
  237.  * Jeżeli znajduje to wyciąga go z tej kolejki, dodaje swój podpis(odznaczając się z rekordu)
  238.  * wrzuca do kolejnej (o ile nie wyciągnął z 3-ciej) wyżej
  239.  */
  240. void *Profesor(void * arg)
  241. {
  242. int id=0;
  243. id=*(int*)arg;
  244. unsigned sz;
  245. while (1)
  246. {
  247. pthread_mutex_lock(&mutex3);
  248. // Sprawdzenie kolejki ze studentami, ktorzy maja juz trzy wpisy
  249. sz= kolejka3.size();
  250. if(!kolejka3.empty())
  251. {
  252. pthread_mutex_lock(&mutex_iostream);
  253. WypiszNaEkran("Profesor sprawdza kolejke3",id,1); //YELLOW
  254. pthread_mutex_unlock(&mutex_iostream);
  255. usleep(100);
  256. for (unsigned j=0; j<sz; j++)
  257. {
  258. if(kolejka3[j]&(1<<id))
  259. {
  260. kolejka3[j]&=~(1<<id); // odznaczamy profesora
  261. kolejka3.erase(kolejka3.begin()+j);
  262. pthread_mutex_lock(&mutex_iostream);
  263. WypiszNaEkran("Profesor dodal swoj wpis(kolejka3)",id, true);
  264. pthread_mutex_unlock(&mutex_iostream);
  265. usleep(10);
  266. }
  267. }
  268. }
  269. pthread_mutex_unlock(&mutex3);
  270. sleep(1);
  271. pthread_mutex_lock(&mutex2);
  272. // Sprawdzenie kolejki ze studentami, ktorzy maja dwa wpisy
  273. sz= kolejka2.size();
  274. if(!kolejka2.empty())
  275. {
  276. pthread_mutex_lock(&mutex_iostream);
  277. WypiszNaEkran("Profesor sprawdza kolejke2",id,2);//RED
  278. pthread_mutex_unlock(&mutex_iostream);
  279. usleep(100);
  280. for (unsigned j=0; j<sz; j++)
  281. {
  282. if(kolejka2[j]&(1<<id))
  283. {
  284. kolejka2[j]&=~(1<<id); // odznaczamy profesora
  285. pthread_mutex_lock(&mutex3);
  286. kolejka3.push_back(kolejka2[j]);
  287. pthread_mutex_unlock(&mutex3);
  288. kolejka2.erase(kolejka2.begin()+j);
  289. pthread_mutex_lock(&mutex_iostream);
  290. WypiszNaEkran("Profesor dodal swoj wpis(kolejka2)",id,true);
  291. pthread_mutex_unlock(&mutex_iostream);
  292. usleep(100);
  293. }
  294. }
  295. }
  296. pthread_mutex_unlock(&mutex2);
  297. sleep(1);
  298. pthread_mutex_lock(&mutex1);
  299. // Sprawdzenie kolejki ze studentami, ktorzy maja jeden wpisy
  300. sz= kolejka1.size();
  301. if(!kolejka1.empty())
  302. {
  303. pthread_mutex_lock(&mutex_iostream);
  304. WypiszNaEkran("Profesor sprawdza kolejke1",id,3); // BLUE
  305. pthread_mutex_unlock(&mutex_iostream);
  306. usleep(100);
  307. for (unsigned j=0; j<sz; j++)
  308. {
  309.  
  310. if(kolejka1[j]&(1<<id))
  311. {
  312. kolejka1[j]&=~(1<<id); // odznaczamy profesora
  313. pthread_mutex_lock(&mutex2);
  314. kolejka2.push_back(kolejka1[j]);
  315. pthread_mutex_unlock(&mutex2);
  316. kolejka1.erase(kolejka1.begin()+j);
  317. pthread_mutex_lock(&mutex_iostream);
  318. WypiszNaEkran("Profesor dodal swoj wpis(kolejka2)",id,true);
  319. pthread_mutex_unlock(&mutex_iostream);
  320. usleep(100);
  321. }
  322. }
  323. }
  324. pthread_mutex_unlock(&mutex1);
  325. sleep(1);
  326. pthread_mutex_lock(&mutex0);
  327. // Sprawdzenie kolejki ze studentami, ktorzy nie maja wpisow
  328. sz= kolejka0.size();
  329. if(!kolejka0.empty())
  330. {
  331. pthread_mutex_lock(&mutex_iostream);
  332. WypiszNaEkran("Profesor sprawdza kolejke0",id,4); // MAGENDA
  333. pthread_mutex_unlock(&mutex_iostream);
  334. usleep(100);
  335. for (unsigned j=0; j<sz; j++)
  336. {
  337.  
  338. if(kolejka0[j]&(1<<id))
  339. {
  340. kolejka0[j]&=~(1<<id); // odznaczamy profesora
  341. pthread_mutex_lock(&mutex1);
  342. kolejka1.push_back(kolejka0[j]);
  343. pthread_mutex_unlock(&mutex1);
  344. kolejka0.erase(kolejka0.begin()+j);
  345. pthread_mutex_lock(&mutex_iostream);
  346. WypiszNaEkran("Profesor dodal swoj wpis(kolejka0)",id,true);
  347. pthread_mutex_unlock(&mutex_iostream);
  348. usleep(100);
  349. }
  350.  
  351. }
  352. }
  353. pthread_mutex_unlock(&mutex0);
  354. sleep(1);
  355. }
  356. }
  357. /*
  358.  * Kod Portiera.
  359.  *
  360.  * Utrzymuje kolejke zerowa by bylo w niej przynajmnie 10 studentów
  361.  * Jezeli jest mniej niz 10 studentow dorabia 10 nowych
  362.  */
  363. void *Portier(void * arg)
  364. {
  365. int id=0;
  366. id=*(int*)arg;
  367. int abc;
  368. while(1)
  369. {
  370. pthread_mutex_lock(&mutex0);
  371. if(kolejka0.size()<10)
  372. {
  373. for(int i=0;i<10;i++)
  374. {
  375. abc=UtworzStudenta();
  376. kolejka0.push_back(abc);
  377. }
  378. }
  379. pthread_mutex_unlock(&mutex0);
  380. usleep(1000000);
  381. }
  382. }
  383.  
  384.  
  385. void *Wyjscie(void * arg)
  386. {
  387. char txt;
  388. do
  389. {
  390. txt = getch();
  391. sleep(1);
  392. }
  393. while( txt != 27 );
  394. exit(1);
  395. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty