Guest User

Untitled

a guest
Jun 14th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.82 KB | None | 0 0
  1. /*
  2. Besturingssystemen: opdracht 1
  3. Academiejaar 2010-2011
  4.  
  5. Naam: Wouter Milants
  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. #include <semaphore.h>
  20. using namespace std;
  21.  
  22. #ifdef WIN32
  23. # include <process.h>
  24. #else
  25. # include <time.h>
  26. #endif
  27.  
  28. static void Error(const char *str)
  29. {
  30. std::cerr << str << std::endl;
  31. exit(0);
  32. }
  33.  
  34. class Data
  35. {
  36. public:
  37. enum Status {BeingProduced, Produced, BeingHandled, Handled, None};
  38.  
  39. Data() : status(None), value(0) {}
  40. void setStatus(Status s) { status = s; }
  41. void setValue(int v) { value = v; }
  42. bool checkStatus(Status s) { return status == s; }
  43. void print(std::ostream &ostr) { ostr << status << ' ' << value << std::endl; }
  44.  
  45. private:
  46. Status status;
  47. int value;
  48. };
  49.  
  50. class Buffer
  51. {
  52. int lastProdIndex;
  53. sem_t wait;
  54. public:
  55. Buffer() {
  56. cout<<"\nconstructor";
  57. sem_init(&wait, 0, 0);
  58. }
  59.  
  60. public:
  61. Data *getEmptyDataElement()
  62. {
  63.  
  64. Data *d;
  65. // if (*lastProduced)
  66. //{
  67. //Data *d /* = empty data element */;
  68. //Data *d =
  69. // }
  70. // else
  71. // {
  72.  
  73. d = &(storage[0]);
  74.  
  75. // }
  76. cout<<"getempty";
  77. if( !d->checkStatus(Data::None) && !d->checkStatus(Data::Handled) )
  78. Error("Error: status of data is wrong during producing");
  79. d->setStatus(Data::BeingProduced);
  80. lastProdIndex = 0;
  81.  
  82.  
  83.  
  84. return d;
  85. }
  86.  
  87. Data *getLastProducedData()
  88. {
  89. cout<<"\nbeforewait";
  90. sem_wait(&wait);
  91. cout<<"afterwait\n";
  92. // Data *d /* = last produced element */;
  93. Data *d = &(storage[lastProdIndex]);
  94. cout<<"beforehandling";
  95. if( d->checkStatus(Data::None) || d->checkStatus(Data::BeingProduced) )
  96. Error("Error: status of data is wrong during handling");
  97. d->setStatus(Data::BeingHandled);
  98. return d;
  99. }
  100.  
  101. void publish(Data *d) /* update last produced, so getLastProducedData returns the correct element */
  102. {
  103. /* previously produced Data element should be emptied if not being handled */
  104. d->setStatus(Data::Produced);
  105. cout<<"\nvoorpost";
  106. sem_post(&wait);
  107. }
  108.  
  109. void release(Data *d) /* update handled element, to make it available via getEmptyDataElement */
  110. {
  111. // if( /* data element no longer being handled */ )
  112. if (! d->checkStatus(Data::BeingHandled) )
  113. {
  114. d->setStatus(Data::Handled);
  115. }
  116. }
  117.  
  118. private:
  119. static const int BUFFERSIZE = 10;
  120. Data storage[BUFFERSIZE];
  121. Data *lastProduced;
  122. };
  123.  
  124. static void *start_thread(void *t);
  125. class Thread
  126. {
  127. public:
  128. Thread() : tid(0) {}
  129.  
  130. void start()
  131. {
  132. if( pthread_create(&tid, 0, start_thread, (void *) this) != 0 )
  133. Error("Error: failed to create thread");
  134. }
  135.  
  136. void wait()
  137. {
  138. void *status;
  139. pthread_join(tid, &status);
  140. }
  141.  
  142. static void sleep(unsigned int msecs)
  143. {
  144. #ifdef WIN32
  145. if( SleepEx(msecs, TRUE) != 0 )
  146. Error("Error: SleepEx interrupted");
  147. #else
  148. struct timespec timeout; // timeout value for wait function
  149.  
  150. // prepare timeout value
  151. timeout.tv_sec = msecs / 1000;
  152. msecs -= timeout.tv_sec * 1000;
  153. timeout.tv_nsec = (1000 * msecs) * 1000;
  154.  
  155. if( nanosleep(&timeout, 0) != 0 )
  156. Error("Error: nanosleep interrupted or failed");
  157. #endif
  158. }
  159.  
  160. virtual void run() = 0;
  161.  
  162. private:
  163. pthread_t tid;
  164. };
  165.  
  166. static void *start_thread(void *t)
  167. {
  168. reinterpret_cast<Thread *>(t)->run();
  169. return 0;
  170. }
  171.  
  172. class Producer : public Thread
  173. {
  174. public:
  175. Producer(Buffer &b, long sequenceNumber) : buffer(b), sequenceNumber(sequenceNumber) {}
  176.  
  177. private:
  178. void run()
  179. {
  180. cout<<"run";
  181. for(int i = 0; i < 1000; ++i)
  182. {
  183. cout<<"loop";
  184. Data *d = buffer.getEmptyDataElement();
  185. cout<<"loop2";
  186. produceData(d);
  187. buffer.publish(d);
  188. }
  189. }
  190.  
  191. void produceData(Data *d)
  192. {
  193. cout<<"pro\n";
  194. Thread::sleep((float(rand()) / RAND_MAX) * 1000); // sleep between 0 and 1 sec
  195. cout<<"qs";
  196. d->setValue(sequenceNumber++);
  197. cout<<"dervoor";
  198. d->print(std::cout);
  199. cout<<"derna";
  200. }
  201.  
  202. Buffer &buffer;
  203. long sequenceNumber;
  204. };
  205.  
  206.  
  207. class Handler : public Thread
  208. {
  209. public:
  210. Handler(Buffer &b, std::ostream &ostr) : buffer(b), ostr(ostr) {}
  211.  
  212. private:
  213.  
  214. void run()
  215. {
  216. Data *d;
  217. // while( /* data available or producer active */ )
  218.  
  219. while (1)
  220. {
  221. cout<<"\nhandlerloop";
  222. d = buffer.getLastProducedData();
  223. handleData(d);
  224. buffer.release(d);
  225. }
  226. }
  227. void handleData(Data *d)
  228. {
  229. d->print(ostr);
  230. Thread::sleep((float(rand()) / RAND_MAX) * 1000); // sleep between 0 and 1 sec
  231. }
  232.  
  233. Buffer &buffer;
  234. std::ostream &ostr;
  235. };
  236.  
  237. int main()
  238. {
  239. Buffer buff;
  240.  
  241. std::ofstream file1;
  242. std::ofstream file2;
  243.  
  244. // open the files
  245. file1.open("C:\\Users\\Wouter\\Desktop\\UHasselt\\BES\\opdracht1\\file1.txt", std::ios::out|std::ios::trunc);
  246. file2.open("C:\\Users\\Wouter\\Desktop\\UHasselt\\BES\\opdracht1\\file2.txt", std::ios::out|std::ios::trunc);
  247.  
  248. Producer p(buff, 0);
  249. cout<<"prodData\n";
  250.  
  251. p.start();
  252.  
  253. Handler h1(buff, std::cout), h2(buff, file1), h3(buff, file2);
  254. cout<<"nahandler";
  255.  
  256. h1.start();
  257. h2.start();
  258. h3.start();
  259.  
  260. // wait until producers stopped producing and handlers handled all produced data
  261.  
  262. return EXIT_SUCCESS;
  263. }
Add Comment
Please, Sign In to add comment