Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <pthread.h>
- #include <unistd.h>
- #include <semaphore.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- // CORRECTED FORMATTED TESTING --> (BUFFER), (BUFFER_POINTER) all to shared memory
- #define SIZE 5
- #define NUMB_THREADS 6
- #define PRODUCER_LOOPS 2
- #define SHMSZ (SIZE * sizeof(int))
- #define SHMSZ2 sizeof(int)
- typedef int buffer_t;
- int *p_buffer;
- int *p_buffer_index;
- sem_t *mutex_sem;
- sem_t *full_sem;
- sem_t *empty_sem;
- void insertbuffer(buffer_t value)
- {
- if (*p_buffer_index < SIZE)
- {
- p_buffer[*p_buffer_index++] = value;
- }
- else
- {
- printf("Buffer overflow\n");
- }
- }
- buffer_t dequeuebuffer()
- {
- if (*p_buffer_index > 0)
- {
- return p_buffer[--*p_buffer_index]; // buffer_index-- would be error!
- }
- else
- {
- printf("Buffer underflow\n");
- }
- return 0;
- }
- void *producer(void *thread_n)
- {
- int thread_numb = *(int *)thread_n;
- buffer_t value;
- int i = 0;
- while (i++ < PRODUCER_LOOPS)
- {
- sleep(rand() % 10);
- value = rand() % 100;
- sem_wait(full_sem); // sem=0: wait. sem>0: go and decrement it
- /* possible race condition here. After this thread wakes up,
- another thread could aqcuire mutex before this one, and add to list.
- Then the list would be full again
- and when this thread tried to insert to buffer there would be
- a buffer overflow error */
- sem_wait(mutex_sem); /* protecting critical section */
- insertbuffer(value);
- sem_post(mutex_sem);
- sem_post(empty_sem); // post (increment) emptybuffer semaphore
- printf("Producer %d added %d to buffer\n", thread_numb, value);
- }
- pthread_exit(0);
- }
- void *consumer(void *thread_n)
- {
- int thread_numb = *(int *)thread_n;
- buffer_t value;
- int i = 0;
- while (i++ < PRODUCER_LOOPS)
- {
- sem_wait(empty_sem);
- /* there could be race condition here, that could cause
- buffer underflow error */
- sem_wait(mutex_sem);
- value = dequeuebuffer();
- sem_post(mutex_sem);
- sem_post(full_sem); // post (increment) fullbuffer semaphore
- printf("Consumer %d dequeue %d from buffer\n", thread_numb, value);
- }
- pthread_exit(0);
- }
- int main(int argc, int **argv)
- {
- // change buffer into shared memory (buffer_t buffer[SIZE])
- int shmidBuff;
- key_t keyBuff;
- int *shmBuff;
- keyBuff = 3111;
- if ((shmidBuff = shmget(keyBuff, SHMSZ, IPC_CREAT | 0666)) < 0)
- {
- perror("shmget");
- exit(1);
- }
- if ((shmBuff = shmat(shmidBuff, NULL, 0)) == (int *)-1)
- {
- perror("shmat");
- exit(1);
- }
- p_buffer = shmBuff;
- // change buffer into shared memory (int buffer_index;)
- int shmidInd;
- key_t keyInd;
- int *shmInd;
- keyInd = 3112;
- if ((shmidInd = shmget(keyInd, SHMSZ2, IPC_CREAT | 0666)) < 0)
- {
- perror("shmget");
- exit(1);
- }
- if ((shmInd = shmat(shmidInd, NULL, 0)) == (int *)-1)
- {
- perror("shmat");
- exit(1);
- }
- p_buffer_index = shmInd;
- *p_buffer_index = 0;
- /////////////////////////////////////
- // Create a shared memory segment
- int shmidmMutex;
- sem_t *shmMutex;
- key_t keyMutex = 3113;
- shmidmMutex = shmget(keyMutex, sizeof(sem_t), IPC_CREAT | 0666);
- if (shmidmMutex == -1)
- {
- perror("shmget");
- exit(1);
- }
- // Attach the shared memory segment to your process
- shmMutex = shmat(shmidmMutex, NULL, 0);
- if (shmMutex == (void *)-1)
- {
- perror("shmat");
- exit(1);
- }
- // Initialize the mutex semaphore on the shared memory
- if (sem_init(shmMutex, 1, 1) == -1)
- {
- perror("sem_init");
- exit(1);
- }
- mutex_sem = shmMutex;
- // Open the other semaphores
- // sem_unlink("/empty_sem");
- empty_sem = sem_open("/empty_sem1111", O_CREAT | O_EXCL, 0644, 0);
- if (empty_sem == SEM_FAILED)
- {
- perror("sem_open empty_sem");
- exit(1);
- }
- // sem_unlink("/full_sem");
- full_sem = sem_open("/full_sem1111", O_CREAT | O_EXCL, 0644, SIZE);
- if (full_sem == SEM_FAILED)
- {
- perror("sem_open full_sem");
- exit(1);
- }
- pthread_t thread[NUMB_THREADS];
- int thread_numb[NUMB_THREADS];
- int i;
- for (i = 0; i < NUMB_THREADS;)
- {
- thread_numb[i] = i;
- pthread_create(thread + i, // pthread_t *t
- NULL, // const pthread_attr_t *attr
- producer, // void *(*start_routine) (void *)
- thread_numb + i); // void *arg
- i++;
- thread_numb[i] = i;
- // playing a bit with thread and thread_numb pointers...
- pthread_create(&thread[i], // pthread_t *t
- NULL, // const pthread_attr_t *attr
- consumer, // void *(*start_routine) (void *)
- &thread_numb[i]); // void *arg
- i++;
- }
- for (i = 0; i < NUMB_THREADS; i++)
- pthread_join(thread[i], NULL);
- // pthread_mutex_destroy(&buffer_mutex);
- sem_destroy(full_sem);
- sem_destroy(empty_sem);
- sem_close(full_sem);
- sem_close(empty_sem);
- sem_unlink("/full_sem");
- sem_unlink("/empty_sem");
- shmdt(p_buffer);
- shmctl(shmidBuff, IPC_RMID, NULL);
- shmdt(p_buffer_index);
- shmctl(shmidInd, IPC_RMID, NULL);
- sem_destroy(mutex_sem);
- shmctl(shmidmMutex, IPC_RMID, NULL);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement