C++ Improving my code - semaphores and mutex

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Nov 2009
Posts: 1
Reputation: hakan5 is an unknown quantity at this point 
Solved Threads: 0
hakan5 hakan5 is offline Offline
Newbie Poster

C++ Improving my code - semaphores and mutex

 
0
  #1
19 Days Ago
Good day.
Here's my code. My uncle helped me with it for days but he's now out of the country for 2 weeks. I'm looking for help to improve this project of mine with mutex and semaphores. I've never used them before and I'm a little confused. I'm running this in Ubuntu Linux. Most of the info is in the comments in my code.

I would appreciate your comments and any suggestions. Where would you guys use the semaphores/mutexes?

Regards,
HÃ¥kan

  1. #include <semaphore.h>
  2. #include <pthread.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. // I'm using g++ to compile this program in Ubuntu 9.04. I use the command ./a.out to run it.
  7.  
  8. /*
  9. The program simulates many producers and consumers.
  10. Producers are many and put products in a joint stack. Consumers are also many and take from this same stack.
  11.  
  12. Only the product number goes into the stack, nothing else.
  13.  
  14. Each producer makes a product number by random from 0..PRODUCTS-1 and puts into the stack. It also raises
  15.  
  16. the appropriate element in array "production" by 1.
  17. It also raises the production_total with 1.
  18.  
  19. Each consumer looks at the number at the top of each stack.
  20. It raises the counter by 1 over what has been
  21.  
  22. "consumed" by that production number by raising the element in the array "consumption". It also raises
  23.  
  24. consumption_total by 1.
  25.  
  26. After all the threads have finished all numbers must match.
  27. The array production must look like the array
  28.  
  29. consumption and production_total must look like consumption_total.
  30.  
  31. The stack must start and end in 0.
  32.  
  33. So that can happen I need to synchronize producers and consumers with semaphors and mutex so they will not
  34.  
  35. interrupt each other. How can I make the threads end? Where should I put the semaphors and mutex?
  36. */
  37.  
  38. #define PRODUCERS 20
  39. #define CONSUMERS 20
  40. #define PRODUCTS 25
  41. #define STACKMAX 100
  42.  
  43. // Producers produce products with a product number between 0..PRODUCTS
  44.  
  45. // array production og consumption store numbers for production and consumption
  46. // for each product.
  47. int production[PRODUCTS];
  48. int production_total;
  49. int consumption[PRODUCTS];
  50. int consumption_total;
  51.  
  52. int stacksize; // stack can be 0..STACKSIZE-1, I need to use semaphore to watch out for highs and lows...
  53. int stack[STACKMAX];
  54.  
  55. // This is how I learnt how to create a semaphore
  56. sem_t semaphore;
  57.  
  58. //This is how a semaphore is usually used:
  59. //sem_wait(&semaphore);
  60. //sem_post(&semaphore);
  61.  
  62.  
  63. //This is how I learnt how to create a mutex - could need more
  64. pthread_mutex_t mutex;
  65. //This is how they're suppoes to be used
  66. //pthread_mutex_lock(&mutex);
  67. //pthread_mutex_unlock(&mutex);
  68.  
  69. #define True 1
  70. #define False 0
  71.  
  72. // If quitting = True then we're stopping and all threads should exit
  73. int quitting;
  74.  
  75.  
  76. void* producer(void *arg)
  77. {
  78. int product_number;
  79.  
  80. printf("I'm a producer\n");
  81.  
  82. return NULL; // This needs to be removed so the code will run
  83.  
  84. // I need to change this code! Here I need at least one semaphore and probably one mutex.
  85. // The
  86.  
  87. if.then.else used here is not the most suitable solution.
  88. while(!quitting)
  89. {
  90. if(stacksize<STACKMAX)
  91. {
  92. product_number=rand()%PRODUCTS; // Some number on between 0..PRODUCTS
  93. // Put on stack
  94. stack[stacksize++]=product_number;
  95.  
  96. // and record it..
  97. production[product_number]++;
  98. production_total++;
  99. }
  100. else
  101. {
  102. printf("The stack is full!\n");
  103. }
  104. }
  105. return NULL;
  106. }
  107.  
  108. void* consumer(void *arg)
  109. {
  110. int product_number;
  111.  
  112. printf("I'm a consumer!\n");
  113.  
  114. return NULL; // This return should delete
  115.  
  116. // I need to change this code! Here I need at least one semaphore and probably one mutex.
  117. // The
  118.  
  119. if.then.else used here is not the most suitable solution.
  120.  
  121. while(!quitting)
  122. {
  123. if(stacksize>0)
  124. {
  125. product_number=stack[--stacksize];
  126. consumption[product_number]++;
  127. consumption_total++;
  128. }
  129. else
  130. {
  131. printf("The stack is empty!\n");
  132. }
  133.  
  134. }
  135. return NULL;
  136. }
  137.  
  138.  
  139. int main(int argc, char **argv)
  140. {
  141. pthread_t consumer_threads[CONSUMERS];
  142. pthread_t producer_threads[PRODUCERS];
  143.  
  144.  
  145. // Initialize the semaphore with a value of 1.
  146. // Note the second argument: passing zero denotes
  147. // that the semaphore is shared between threads (and
  148. // not processes).
  149. if(sem_init(&semaphore, 0, 1))
  150. {
  151. printf("Could not initialize a semaphore\n");
  152. return -1;
  153. }
  154.  
  155. // Initialize the mutex
  156. if(pthread_mutex_init(&mutex, NULL))
  157. {
  158. printf("Unable to initialize a mutex\n");
  159. return -1;
  160. }
  161.  
  162. // Null random generator
  163. srand(0);
  164.  
  165. // Null all counters
  166. stacksize=0;
  167. consumption_total=0;
  168. production_total=0;
  169. for(int i=0;i<PRODUCTS;i++)
  170. {
  171. consumption[i]=0;
  172. production[i]=0;
  173. }
  174.  
  175. // Consumers can look at this global variable to see if producers have stopped producing // and it's
  176.  
  177. safe to quit
  178. quitting=False;
  179.  
  180. // Print initial values
  181. printf("stacksize (should be 0) = %i\n",stacksize);
  182. printf("production_total = %i\n",production_total);
  183. printf("consumption_total = %i (needs to match production)\n",consumption_total);
  184.  
  185. printf("Production array broken down:\n");
  186. for(int i=0;i<PRODUCTS;i++)
  187. {
  188. printf("%i ",production[i]);
  189. }
  190. printf("\n");
  191.  
  192. printf("Consumption array broken down (needs to match production array):\n");
  193. for(int i=0;i<PRODUCTS;i++)
  194. {
  195. printf("%i ",consumption[i]);
  196. }
  197. printf("\n");
  198.  
  199.  
  200. // Start the producer
  201.  
  202. for(int i = 0; i < PRODUCERS; ++i)
  203. {
  204. if(pthread_create(&producer_threads[i], NULL, &producer, NULL))
  205. {
  206. printf("Could not create thread %d\n", i);
  207. return -1;
  208. }
  209. }
  210.  
  211. // Start the consumer
  212.  
  213. int thread_count=0;
  214.  
  215. for(int i = 0; i < CONSUMERS; ++i)
  216. {
  217. if(pthread_create(&consumer_threads[i], NULL, &consumer, NULL))
  218. {
  219. printf("Could not create thread %d\n", i);
  220. return -1;
  221. }
  222. }
  223.  
  224. // The main program sleeps for a while
  225. // then puts the global variable qutting = True , by that all consumers and producers
  226. //should stop
  227.  
  228. producing.
  229. sleep(3);
  230. quitting=True;
  231. printf("Now the main program wants to quit...\n");
  232.  
  233.  
  234. for(int i = 0; i < CONSUMERS; ++i)
  235. {
  236. if(pthread_join(consumer_threads[i], NULL))
  237. {
  238. printf("Could not join thread %d\n", i);
  239. return -1;
  240. }
  241. }
  242.  
  243. for(int i = 0; i < PRODUCERS; ++i)
  244. {
  245. if(pthread_join(producer_threads[i], NULL))
  246. {
  247. printf("Could not join thread %d\n", i);
  248. return -1;
  249. }
  250. }
  251.  
  252. printf("All threads are dead\n");
  253.  
  254. sem_destroy(&semaphore);
  255. pthread_mutex_destroy(&mutex);
  256.  
  257. printf("All over.. now everything should match\n");
  258. printf("stacksize (should be 0) = %i\n",stacksize);
  259. printf("production_total = %i\n",production_total);
  260. printf("consumption_total = %i (needs to match production)\n",consumption_total);
  261.  
  262. printf("Production array broken down:\n");
  263. for(int i=0;i<PRODUCTS;i++)
  264. {
  265. printf("%i ",production[i]);
  266. }
  267. printf("\n");
  268.  
  269. printf("Consumption array broken down (needs to match production array):\n");
  270. for(int i=0;i<PRODUCTS;i++)
  271. {
  272. printf("%i ",consumption[i]);
  273. }
  274. printf("\n");
  275.  
  276. return 0;
  277. }
Attached Files
File Type: cpp project_1.cpp (7.1 KB, 1 views)
Reply With Quote Quick reply to this message  
Reply

Message:



Similar Threads
Other Threads in the C++ Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC