Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'simgrid-udpor-integration' into 'master'
[simgrid.git] / examples / sthread / pthread-producer-consumer.c
1 /* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 /* Simple producer/consumer example with pthreads and semaphores */
7
8 #include <pthread.h>
9 #include <semaphore.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #define AmountProduced 3 /* Amount of items produced by a producer */
15 #define AmountConsumed 3 /* Amount of items consumed by a consumer */
16 #define ProducerCount 2  /* Amount of producer threads*/
17 #define ConsumerCount 2  /* Amount of consumer threads*/
18 #define BufferSize 4     /* Size of the buffer */
19
20 sem_t empty;
21 sem_t full;
22 int in  = 0;
23 int out = 0;
24 int buffer[BufferSize];
25 pthread_mutex_t mutex;
26 int do_output = 1;
27
28 static void* producer(void* id)
29 {
30   for (int i = 0; i < AmountProduced; i++) {
31     sem_wait(&empty);
32     pthread_mutex_lock(&mutex);
33     buffer[in] = i;
34     if (do_output)
35       fprintf(stderr, "Producer %d: Insert Item %d at %d\n", *((int*)id), buffer[in], in);
36     in = (in + 1) % BufferSize;
37     pthread_mutex_unlock(&mutex);
38     sem_post(&full);
39   }
40   return NULL;
41 }
42 static void* consumer(void* id)
43 {
44   for (int i = 0; i < AmountConsumed; i++) {
45     sem_wait(&full);
46     pthread_mutex_lock(&mutex);
47     int item = buffer[out];
48     if (do_output)
49       fprintf(stderr, "Consumer %d: Remove Item %d from %d\n", *((int*)id), item, out);
50     out = (out + 1) % BufferSize;
51     pthread_mutex_unlock(&mutex);
52     sem_post(&empty);
53   }
54   return NULL;
55 }
56
57 int main(int argc, char** argv)
58 {
59   if (argc == 2 && strcmp(argv[1], "-q") == 0)
60     do_output = 0;
61   pthread_t pro[2];
62   pthread_t con[2];
63   pthread_mutex_init(&mutex, NULL);
64   sem_init(&empty, 0, BufferSize);
65   sem_init(&full, 0, 0);
66
67   int ids[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // The identity of each thread (for debug messages)
68
69   for (int i = 0; i < ProducerCount; i++)
70     pthread_create(&pro[i], NULL, producer, &ids[i]);
71   for (int i = 0; i < ConsumerCount; i++)
72     pthread_create(&con[i], NULL, consumer, &ids[i]);
73
74   for (int i = 0; i < ProducerCount; i++)
75     pthread_join(pro[i], NULL);
76   for (int i = 0; i < ConsumerCount; i++)
77     pthread_join(con[i], NULL);
78
79   pthread_mutex_destroy(&mutex);
80   sem_destroy(&empty);
81   sem_destroy(&full);
82
83   return 0;
84 }