Advertisement
Guest User

Untitled

a guest
Aug 20th, 2017
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.88 KB | None | 0 0
  1. /*
  2. Besturingssystemen: opdracht 1
  3. Academiejaar 2016-2017
  4.  
  5. Naam: ...
  6. */
  7.  
  8. /*
  9. Lees aandachtig de commentaar in de code!
  10.  
  11. Je mag overal waar je dat nodig acht code aanvullen,
  12. dus niet enkel op de plaatsen waar commentaar staat.
  13. */
  14.  
  15. #include <iostream>
  16. #include <fstream>
  17. #include <pthread.h>
  18. #include <stdlib.h>
  19.  
  20. #ifdef WIN32
  21. # include <process.h>
  22. #else
  23. # include <time.h>
  24. #endif
  25.  
  26. static void Error(const char *str)
  27. {
  28. std::cerr << str << std::endl;
  29. exit(0);
  30. }
  31.  
  32. class Data
  33. {
  34. public:
  35. Data() : refcount(0), value(0) {}
  36. void ref() { refcount++; }
  37. void unref() { refcount--; }
  38. bool isUnused(){ return ( refcount == 0 ); }
  39. void setValue(int val){ value = val; }
  40. void print(std::ostream &ostr) { ostr << value << std::endl; }
  41.  
  42. private:
  43. unsigned int refcount;
  44. int value;
  45. };
  46.  
  47. class Buffer
  48. {
  49. public:
  50. Buffer() : lastProduced(0) {}
  51.  
  52. public:
  53. Data *getEmptyDataElement()
  54. {
  55. Data *d = 0; /* = empty data element */;
  56. for (int i=0; i<BUFFERSIZE; i++)
  57. {
  58. if (/* element is free */) {
  59. d = &storage[i];
  60. break;
  61. }
  62. }
  63.  
  64. return d;
  65. }
  66.  
  67. Data *getLastProducedData(Data* previous)
  68. {
  69. // check if new element is available
  70. Data *d = lastProduced;
  71. d->ref();
  72. return d;
  73. }
  74.  
  75. void publish(Data *d) /* update last produced, so getLastProducedData returns the correct element */
  76. {
  77. lastProduced = d;
  78. }
  79.  
  80. void release(Data *d) /* update handled element, to make it available via getEmptyDataElement */
  81. {
  82. d->unref();
  83. }
  84.  
  85. private:
  86. static const int BUFFERSIZE = 10;
  87. Data storage[BUFFERSIZE];
  88. Data *lastProduced;
  89. };
  90.  
  91. static void *start_thread(void *t);
  92. class Thread
  93. {
  94. public:
  95. Thread() : tid(0) {}
  96.  
  97. void start()
  98. {
  99. if( pthread_create(&tid, 0, start_thread, (void *) this) != 0 )
  100. Error("Error: failed to create thread");
  101. }
  102.  
  103. void wait()
  104. {
  105. void *status;
  106. pthread_join(tid, &status);
  107. }
  108.  
  109. static void sleep(unsigned int msecs)
  110. {
  111. #ifdef WIN32
  112. if( SleepEx(msecs, TRUE) != 0 )
  113. Error("Error: SleepEx interrupted");
  114. #else
  115. struct timespec timeout; // timeout value for wait function
  116.  
  117. // prepare timeout value
  118. timeout.tv_sec = msecs / 1000;
  119. msecs -= timeout.tv_sec * 1000;
  120. timeout.tv_nsec = (1000 * msecs) * 1000;
  121.  
  122. if( nanosleep(&timeout, 0) != 0 )
  123. Error("Error: nanosleep interrupted or failed");
  124. #endif
  125. }
  126.  
  127. virtual void run() = 0;
  128.  
  129. private:
  130. pthread_t tid;
  131. };
  132.  
  133. static void *start_thread(void *t)
  134. {
  135. reinterpret_cast<Thread *>(t)->run();
  136. return 0;
  137. }
  138.  
  139. class Producer : public Thread
  140. {
  141. public:
  142. Producer(Buffer &b, long sequenceNumber) : buffer(b), sequenceNumber(sequenceNumber) {}
  143.  
  144. private:
  145. void run()
  146. {
  147. for(int i = 0; i < 1000; ++i)
  148. {
  149. Data *d = buffer.getEmptyDataElement();
  150. produceData(d);
  151. buffer.publish(d);
  152. }
  153. }
  154.  
  155. void produceData(Data *d)
  156. {
  157. Thread::sleep((float(rand()) / RAND_MAX) * 1000); // sleep between 0 and 1 sec
  158. d->setValue(sequenceNumber++);
  159. d->print(std::cout);
  160. }
  161.  
  162. Buffer &buffer;
  163. long sequenceNumber;
  164. };
  165.  
  166.  
  167. class Handler : public Thread
  168. {
  169. public:
  170. Handler(Buffer &b, std::ostream &ostr) : buffer(b), ostr(ostr) {}
  171.  
  172. private:
  173. void run()
  174. {
  175. Data *previous = 0;
  176. while( /* data available or producer active */ )
  177. {
  178. Data *d = buffer.getLastProducedData(previous);
  179. handleData(d);
  180. buffer.release(d);
  181. previous = d;
  182. }
  183. }
  184. void handleData(Data *d)
  185. {
  186. d->print(ostr);
  187. Thread::sleep((float(rand()) / RAND_MAX) * 1000); // sleep between 0 and 1 sec
  188. }
  189.  
  190. Buffer &buffer;
  191. std::ostream &ostr;
  192. };
  193.  
  194. int main()
  195. {
  196. Buffer buff;
  197.  
  198. std::ofstream file1;
  199. std::ofstream file2;
  200.  
  201. // open the files
  202.  
  203. Producer p(buff, 0);
  204. Handler h1(buff, std::cout), h2(buff, file1), h3(buff, file2);
  205.  
  206. p.start();
  207. h1.start();
  208. h2.start();
  209. h3.start();
  210.  
  211. // wait until producers stopped producing and handlers handled all produced data
  212.  
  213. return EXIT_SUCCESS;
  214. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement