Advertisement
Guest User

PrintServer

a guest
Mar 31st, 2023
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.74 KB | Source Code | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <unistd.h>
  5. #include <semaphore.h>
  6. #include <sys/time.h>
  7. #include <sys/types.h>
  8. #include <sys/ipc.h>
  9. #include <sys/shm.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12.  
  13. // CORRECTED FORMATTED TESTING --> (BUFFER), (BUFFER_POINTER) all to shared memory
  14.  
  15. #define SIZE 5
  16. #define NUMB_THREADS 6
  17. #define PRODUCER_LOOPS 2
  18. #define SHMSZ (SIZE * sizeof(int))
  19. #define SHMSZ2 sizeof(int)
  20.  
  21. typedef int buffer_t;
  22. int *p_buffer;
  23. int *p_buffer_index;
  24. sem_t *mutex_sem;
  25. sem_t *full_sem;
  26. sem_t *empty_sem;
  27.  
  28. void insertbuffer(buffer_t value)
  29. {
  30. if (*p_buffer_index < SIZE)
  31. {
  32. p_buffer[*p_buffer_index++] = value;
  33. }
  34. else
  35. {
  36. printf("Buffer overflow\n");
  37. }
  38. }
  39.  
  40. buffer_t dequeuebuffer()
  41. {
  42. if (*p_buffer_index > 0)
  43. {
  44. return p_buffer[--*p_buffer_index]; // buffer_index-- would be error!
  45. }
  46. else
  47. {
  48. printf("Buffer underflow\n");
  49. }
  50. return 0;
  51. }
  52.  
  53. void *producer(void *thread_n)
  54. {
  55. int thread_numb = *(int *)thread_n;
  56. buffer_t value;
  57. int i = 0;
  58. while (i++ < PRODUCER_LOOPS)
  59. {
  60. sleep(rand() % 10);
  61. value = rand() % 100;
  62.  
  63. sem_wait(full_sem); // sem=0: wait. sem>0: go and decrement it
  64. /* possible race condition here. After this thread wakes up,
  65. another thread could aqcuire mutex before this one, and add to list.
  66. Then the list would be full again
  67. and when this thread tried to insert to buffer there would be
  68. a buffer overflow error */
  69. sem_wait(mutex_sem); /* protecting critical section */
  70. insertbuffer(value);
  71. sem_post(mutex_sem);
  72. sem_post(empty_sem); // post (increment) emptybuffer semaphore
  73. printf("Producer %d added %d to buffer\n", thread_numb, value);
  74. }
  75. pthread_exit(0);
  76. }
  77.  
  78. void *consumer(void *thread_n)
  79. {
  80. int thread_numb = *(int *)thread_n;
  81. buffer_t value;
  82. int i = 0;
  83. while (i++ < PRODUCER_LOOPS)
  84. {
  85.  
  86. sem_wait(empty_sem);
  87. /* there could be race condition here, that could cause
  88. buffer underflow error */
  89. sem_wait(mutex_sem);
  90. value = dequeuebuffer();
  91. sem_post(mutex_sem);
  92. sem_post(full_sem); // post (increment) fullbuffer semaphore
  93. printf("Consumer %d dequeue %d from buffer\n", thread_numb, value);
  94. }
  95. pthread_exit(0);
  96. }
  97.  
  98. int main(int argc, int **argv)
  99. {
  100. // change buffer into shared memory (buffer_t buffer[SIZE])
  101. int shmidBuff;
  102. key_t keyBuff;
  103. int *shmBuff;
  104. keyBuff = 3111;
  105. if ((shmidBuff = shmget(keyBuff, SHMSZ, IPC_CREAT | 0666)) < 0)
  106. {
  107. perror("shmget");
  108. exit(1);
  109. }
  110.  
  111. if ((shmBuff = shmat(shmidBuff, NULL, 0)) == (int *)-1)
  112. {
  113. perror("shmat");
  114. exit(1);
  115. }
  116. p_buffer = shmBuff;
  117.  
  118. // change buffer into shared memory (int buffer_index;)
  119. int shmidInd;
  120. key_t keyInd;
  121. int *shmInd;
  122. keyInd = 3112;
  123. if ((shmidInd = shmget(keyInd, SHMSZ2, IPC_CREAT | 0666)) < 0)
  124. {
  125. perror("shmget");
  126. exit(1);
  127. }
  128.  
  129. if ((shmInd = shmat(shmidInd, NULL, 0)) == (int *)-1)
  130. {
  131. perror("shmat");
  132. exit(1);
  133. }
  134. p_buffer_index = shmInd;
  135. *p_buffer_index = 0;
  136.  
  137. /////////////////////////////////////
  138. // Create a shared memory segment
  139. int shmidmMutex;
  140. sem_t *shmMutex;
  141. key_t keyMutex = 3113;
  142.  
  143. shmidmMutex = shmget(keyMutex, sizeof(sem_t), IPC_CREAT | 0666);
  144. if (shmidmMutex == -1)
  145. {
  146. perror("shmget");
  147. exit(1);
  148. }
  149.  
  150. // Attach the shared memory segment to your process
  151. shmMutex = shmat(shmidmMutex, NULL, 0);
  152. if (shmMutex == (void *)-1)
  153. {
  154. perror("shmat");
  155. exit(1);
  156. }
  157.  
  158. // Initialize the mutex semaphore on the shared memory
  159. if (sem_init(shmMutex, 1, 1) == -1)
  160. {
  161. perror("sem_init");
  162. exit(1);
  163. }
  164.  
  165. mutex_sem = shmMutex;
  166.  
  167. // Open the other semaphores
  168. // sem_unlink("/empty_sem");
  169.  
  170. empty_sem = sem_open("/empty_sem1111", O_CREAT | O_EXCL, 0644, 0);
  171. if (empty_sem == SEM_FAILED)
  172. {
  173. perror("sem_open empty_sem");
  174. exit(1);
  175. }
  176.  
  177. // sem_unlink("/full_sem");
  178.  
  179. full_sem = sem_open("/full_sem1111", O_CREAT | O_EXCL, 0644, SIZE);
  180. if (full_sem == SEM_FAILED)
  181. {
  182. perror("sem_open full_sem");
  183. exit(1);
  184. }
  185.  
  186. pthread_t thread[NUMB_THREADS];
  187. int thread_numb[NUMB_THREADS];
  188. int i;
  189. for (i = 0; i < NUMB_THREADS;)
  190. {
  191. thread_numb[i] = i;
  192. pthread_create(thread + i, // pthread_t *t
  193. NULL, // const pthread_attr_t *attr
  194. producer, // void *(*start_routine) (void *)
  195. thread_numb + i); // void *arg
  196. i++;
  197. thread_numb[i] = i;
  198. // playing a bit with thread and thread_numb pointers...
  199. pthread_create(&thread[i], // pthread_t *t
  200. NULL, // const pthread_attr_t *attr
  201. consumer, // void *(*start_routine) (void *)
  202. &thread_numb[i]); // void *arg
  203. i++;
  204. }
  205.  
  206. for (i = 0; i < NUMB_THREADS; i++)
  207. pthread_join(thread[i], NULL);
  208.  
  209. // pthread_mutex_destroy(&buffer_mutex);
  210.  
  211. sem_destroy(full_sem);
  212. sem_destroy(empty_sem);
  213.  
  214. sem_close(full_sem);
  215. sem_close(empty_sem);
  216. sem_unlink("/full_sem");
  217. sem_unlink("/empty_sem");
  218.  
  219. shmdt(p_buffer);
  220. shmctl(shmidBuff, IPC_RMID, NULL);
  221.  
  222. shmdt(p_buffer_index);
  223. shmctl(shmidInd, IPC_RMID, NULL);
  224.  
  225. sem_destroy(mutex_sem);
  226. shmctl(shmidmMutex, IPC_RMID, NULL);
  227. return 0;
  228. }
  229.  
Tags: code c
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement