I'm having an issue with my sleep cycles in the ProducerConsumer.h file. If I comment out the sleep(rnum) the program will access the line printf("producer produced %d\n", item); If it's not commented out it will never access that line and I cant figure out why.
Here is my code it's in 3 separate files I would be grateful of any help thank you.
buffer.h:
typedef int buffer_item;
#define BUFFER_SIZE 5
int insert_item(buffer_item item);
int remove_item(buffer_item *item);
ProducerConsumer.h:
#include <stdlib.h> /* required for rand() */
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <iostream>
#include "buffer.h"
#define RAND_DIVISOR 100000000;
#define TRUE 1
int counter;
buffer_item buffer[BUFFER_SIZE];
pthread_mutex_t mutex;
sem_t full, empty;
/* Producer Thread */
void *producer(void *param) {
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
printf("producer produced %d\n", item);
/* generate a random number */
item = rand();
/* acquire the empty lock */
sem_wait(&empty);
/* acquire the mutex lock */
pthread_mutex_lock(&mutex);
if(insert_item(item)) {
fprintf(stderr, " Producer report error condition\n");
} else {
printf("producer produced %d\n", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal full */
sem_post(&full);
}
}
/* Consumer Thread */
void *consumer(void *param) {
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* aquire the full lock */
sem_wait(&full);
/* aquire the mutex lock */
pthread_mutex_lock(&mutex);
if(remove_item(&item)) {
fprintf(stderr, "Consumer report error condition\n");
} else {
printf("consumer consumed %d\n", item);`enter code here`
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal empty */
sem_post(&empty);
}
}
int insert_item(buffer_item item) {
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
} else {
return -1;
}
}
int remove_item(buffer_item *item) {
if(counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
} else {
return -1;
}
}
main.cpp:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include "ProducerConsumer.h"
#include "buffer.h"
pthread_t tid;
pthread_attr_t attr;
void initializeData()
{
pthread_mutex_init(&mutex, NULL);
sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFFER_SIZE);
pthread_attr_init(&attr);
counter = 0;
}
int main() {
int i;
int numProd = 5; /* Number of producer threads */
int numCons = 5; /* Number of consumer threads */
initializeData();
/* Create the producer threads */
for(i = 0; i < numProd; i++) {
/* Create the thread */
pthread_create(&tid,&attr,producer,NULL);
}
/* Create the consumer threads */
for(i = 0; i < numCons; i++) {
/* Create the thread */
pthread_create(&tid,&attr,consumer,NULL);
}
void *producer(void *param);
void *consumer(void *param);
/* Exit the program */
printf("Exit the program\n");
exit(0);
}
The RAND_MAX value is likely at least 32767, causing the the following line:
int rNum = rand() / RAND_DIVISOR;// defined as 100000000
to most always set rNum == 0.
Change statement to get a non-zero value:
int rNum = 1 + rand() % 10;// yields 1-10
Also, call srand() one time, and before using rand(). eg:
void *producer(void *param) {
buffer_item item;
srand((unsigned) time(&t));
...
Related
This is my current code for the Producer-Consumer problem. I compiled it and ran it but nothing is printed. The command line takes in 3 arguments: Sleep time, producer threads, consumer threads. I've tried setting the values as 5, 1, 1 respectively, the sleep timer works but I'm unsure about the rest.
Code for buffer.h:
typedef int buffer_item;
#define BUFFER_SIZE 5
Code for buffer.c:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include "buffer.h"
buffer_item buffer[BUFFER_SIZE];
void *producer(void *param);
void *consumer(void *param);
pthread_mutex_t mutex;
sem_t empty;
sem_t full;
int insert_item(buffer_item item)
{
do
{
wait(empty);
wait(mutex);
signal(mutex);
signal(full);
}while(1);
return 0;
}
int remove_item(buffer_item *item)
{
do
{
wait(full);
wait(mutex);
signal(mutex);
signal(empty);
}while(1);
return 0;
}
int main(int argc, char *argv[])
{
int sleepTime;
int producerThreads;
int consumerThreads;
int counter_1;
int counter_2;
if(argc != 4)
{
return -1;
}
sleepTime = atoi(argv[1]);
producerThreads = atoi(argv[2]);
consumerThreads = atoi(argv[3]);
srand((unsigned)time(NULL));
for(counter_1 = 0; counter_1 < producerThreads; counter_1++)
{
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, producer, NULL);
}
for(counter_2 = 0; counter_2 < consumerThreads; counter_2++)
{
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, consumer, NULL);
}
sleep(sleepTime);
return 0;
}
void *producer(void *param)
{
buffer_item item;
int randomTime;
int counter_1 = 0;
while(1)
{
randomTime = rand() % 1000 + 1;
sleep(randomTime);
item = rand();
if(insert_item(item))
{
fprintf(stderr, "Error.");
}
else
{
printf("Producer ID: %lu, Produced Item: %d\n", pthread_self(), item);
printf("The buffer now contains %d items\n", counter_1);
++counter_1;
}
}
}
void *consumer(void *param)
{
buffer_item item;
int randomTime;
int counter_2 = 0;
while(1)
{
randomTime = rand() % 1000 + 1;
sleep(randomTime);
if(insert_item(item))
{
fprintf(stderr, "Error.");
}
else
{
printf("Consumer ID: %lu, Consumed Item: %d\n", pthread_self(), item);
printf("The buffer now contains %d items\n", counter_2);
++counter_2;
}
}
}
So far I've tried declaring the tid separately, skipping sleep and join the threads, but it still doesn't print.
Your code can't possibly run, indeed it doesn't even compile.
Here's a list of issues that need to be addressed:
wait should be sem_wait
signal should be sem_post for semaphores
int sem_wait(sem_t *sem); and int sem_post(sem_t *sem); take the pointer to a semaphore
sem_wait(mutex) and sem_post(mutex) give something like "incompatible type for argument 1 of sem_wait", I guess you want to acquire and release the lock on the mutex like pthread_mutex_lock(&mutex) and pthread_mutex_unlock(&mutex)
in the consumer if(insert_item(item)): item is used uninitialized
still in the consumer you use insert_item instead of remove_item
Coming to the main question "I compiled it and ran it but nothing is printed", it doesn't print anything because producer and consumer call, respectively, insert_item and remove_item and are trapped inside infinite loops (e.g. while(1))
Trying to compile my code in linux by doing gcc -o consumer.c -lpthread -lm and I am getting compile errors about having undeclared for things I, to the best of my knowledge, have declared. Most of the undeclared seem to be related to buffers, of which this is my first program using buffers. Here are the errors (edited to reflect changes)
typedef char buffer_item buffer[BUFFER_SIZE]; // asm or __attribute__ before "buffer"
both of these(expected ')' before 'item'
int insert_item(buffer_item item)
int insert_item(buffer_item item)
int remove_item(buffer_item *item) //expected ')' before * token
and here is my full code after the changes
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define RAND_DIVISOR 100000000
#define TRUE 1
#define BUFFER_SIZE 1000
pthread_mutex_t mutex; //mutex lock
sem_t full, empty; //semaphores
typedef char buffer_item buffer[BUFFER_SIZE];
int counter; //buffer counter
pthread_t tid1, tid2; //Thread ID
pthread_attr_t attr; // thread attributes
void *producer(void *param); // producer thread
void *consumer(void *param); //consumer thread
void initializeData() {
pthread_mutex_init(&mutex, NULL); //Create mutex lock
sem_init(&full, 0, 0); // Create the full semaphore and initialize to 0
sem_init(&empty, 0, BUFFER_SIZE); // Create the empty semaphore and initialize to BUFFER_SIZE
pthread_attr_init(&attr); //default attributes
counter = 0;
}
// Producer Thread
int insert_item(buffer_item item)
void *producer(void *param) {
while(TRUE) {
// random sleep time
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
int item = rand()%100; // item is a random number between 1-100
sem_wait(&empty); //get empty lock
pthread_mutex_lock(&mutex); //get mutex lock
if(insert_item(item)) {
fprintf(stderr, " Producer report error condition\n");
}
else {
printf("producer produced %d\n", item);
}
pthread_mutex_unlock(&mutex); //release mutex lock
sem_post(&full); //signal full
}
}
// Consumer Thread
void *consumer(void *param) {
while(TRUE) {
int rNum = rand() / RAND_DIVISOR; // sleep for a random period of time
sleep(rNum);
int item = rand()%100; // item is a random number between 1-100
sem_wait(&full);// aquire the full lock */
pthread_mutex_lock(&mutex);// aquire the mutex lock
if(remove_item(&item)) {
fprintf(stderr, "Consumer report error condition\n");
}
else {
printf("consumer consumed %d\n", item);
}
pthread_mutex_unlock(&mutex);// release mutex lock
sem_post(&empty); //signal empty
}
}
int insert_item(buffer_item item)
{
// add item as long as buffer isn't full
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
}
else {
return -1; //buffer full error
}
}
// Remove an item from the buffer
int remove_item(buffer_item *item)// remove item and decrement counter when buffer not empty
{
if(counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
}
else { //buffer empty error
}
return -1;
}
int main(int argc, char *argv[]) {
int i; //loop counter
if(argc != 4) {
fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT>\n");
}
int mainSleepTime = atoi(argv[1]); // sleep time in seconds
int numProd = atoi(argv[2]); // producer threads
int numCons = atoi(argv[3]); // consumer threads
initializeData(); //initialize app
for(i = 0; i < numProd; i++) {
pthread_create(&tid1,&attr,producer,NULL);
}
for(i = 0; i < numCons; i++) {
pthread_create(&tid2,&attr,consumer,NULL);
}
// sleep in milliseconds
//sleep(mainSleepTime);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("Program Exiting\n");
exit(0);
}
Edit: latest code and screenshot of errors http://tinypic.com/r/xptzww/9
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define RAND_DIVISOR 100000000
#define TRUE 1
#define BUFFER_SIZE 1000
pthread_mutex_t mutex; //mutex lock
sem_t full, empty; //semaphores
typedef char buffer_item;
int counter; //buffer counter
pthread_t tid1, tid2; //Thread ID
pthread_attr_t attr; // thread attributes
void *producer(void *param); // producer thread
void *consumer(void *param); //consumer thread
void initializeData() {
pthread_mutex_init(&mutex, NULL); //Create mutex lock
sem_init(&full, 0, 0); // Create the full semaphore and initialize to 0
sem_init(&empty, 0, BUFFER_SIZE); // Create the empty semaphore and initialize to BUFFER_SIZE
pthread_attr_init(&attr); //default attributes
counter = 0;
}
// Producer Thread
int insert_item(buffer_item item)
void *producer(void *param) {
while(TRUE) {
// random sleep time
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
int item = rand()%100; // item is a random number between 1-100
sem_wait(&empty); //get empty lock
pthread_mutex_lock(&mutex); //get mutex lock
if(insert_item(item)) {
fprintf(stderr, " Producer report error condition\n");
}
else {
printf("producer produced %d\n", item);
}
pthread_mutex_unlock(&mutex); //release mutex lock
sem_post(&full); //signal full
}
}
// Consumer Thread
void *consumer(void *param) {
while(TRUE) {
int rNum = rand() / RAND_DIVISOR; // sleep for a random period of time
sleep(rNum);
int item = rand()%100; // item is a random number between 1-100
sem_wait(&full);// aquire the full lock */
pthread_mutex_lock(&mutex);// aquire the mutex lock
if(remove_item(&item)) {
fprintf(stderr, "Consumer report error condition\n");
}
else {
printf("consumer consumed %d\n", item);
}
pthread_mutex_unlock(&mutex);// release mutex lock
sem_post(&empty); //signal empty
}
}
int insert_item(buffer_item item){// add item as long as buffer isn't full
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
}
else {
return -1; //buffer full error
}
}
// Remove an item from the buffer
int remove_item(buffer_item *item)// remove item and decrement counter when buffer not empty
{
if(counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
}
else { //buffer empty error
}
return -1;
}
int main(int argc, char *argv[]) {
int i; //loop counter
if(argc != 4) {
fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT>\n");
}
int mainSleepTime = atoi(argv[1]); // sleep time in seconds
int numProd = atoi(argv[2]); // producer threads
int numCons = atoi(argv[3]); // consumer threads
initializeData(); //initialize app
for(i = 0; i < numProd; i++) {
pthread_create(&tid1,&attr,producer,NULL);
}
for(i = 0; i < numCons; i++) {
pthread_create(&tid2,&attr,consumer,NULL);
}
// sleep in milliseconds
//sleep(mainSleepTime);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("Program Exiting\n");
exit(0);
}
You have declared but not defined BUFFER_SIZE.
Instead
char BUFFER_SIZE;
try
char BUFFER_SIZE = some_value;
where some_value should be anything between 1-255
Line:
char buffer_item buffer[BUFFER_SIZE];
should be:
char buffer_item[BUFFER_SIZE];
A variable declaration should look like:
<type name> <variable name>;
There is no standard type buffer_item. If you want to use custom type name it can be defined:
typedef char buffer_item;
I assume that you wanted to use char for that type, since item should keep numbers from 0 to 99 and the char type is enough for that.
After that line the name buffer_item is alias for char. So variables can be declared as buffer_item buffer[BUFFER_SIZE]; or buffer_item item;.
In that case lines like char buffer_item; are redundant. Also you do not need to write char before buffer_item, since buffer_item is already another name for char, so char buffer_item; is the same as char char; that does not make any sense.
Probably that the unknow symbol BUFFER_SIZE should defined as you define #define RAND_DIVISOR 100000000. Typically capital letters in names in C are used for macro definitions. So, you may want to set that size on the top of your file, for example:
#define BUFFER_SIZE 1000
In that case the line char BUFFER_SIZE; is not needed anymore.
You use function insert_item before its declaration. So, to compile that you may put forward declaration also on top before producer():
int insert_item(buffer_item item);
That should be enough to compile the code.
Updated for new errors
Type declaration uses special keyword typedef to create type alias. Here to declare that buffer_item name is used as a type name and it is the same as char it should be exactly:
typedef char buffer_item;
The buffer array should be defined below as:
buffer_item buffer[BUFFER_SIZE];
Forward function declaration requires semicolon at the end:
int insert_item(buffer_item item);
I'm not sure that it will work as expected, but now it should be compiled.
Hi im trying to do the producer/consumer problem on a ubuntu virtual image using vmware. I got the code from here : http://macboypro.wordpress.com/2009/05/25/producer-consumer-problem-using-cpthreadsbounded-buffer/ but i just keep getting "segmentation fault (core dumped)". Any help would be great or even a more clean solution to the producer/consumer problem (bounded buffer problem).
Heres the code im using but due to errors i had to take out the '#include "buffer.h"' :
/* buffer.h */
typedef int buffer_item;
#define BUFFER_SIZE 5
/* main.c */
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include "buffer.h"
#define RAND_DIVISOR 100000000
#define TRUE 1
/* The mutex lock */
pthread_mutex_t mutex;
/* the semaphores */
sem_t full, empty;
/* the buffer */
buffer_item buffer[BUFFER_SIZE];
/* buffer counter */
int counter;
pthread_t tid; //Thread ID
pthread_attr_t attr; //Set of thread attributes
void *producer(void *param); /* the producer thread */
void *consumer(void *param); /* the consumer thread */
void initializeData() {
/* Create the mutex lock */
pthread_mutex_init(&mutex, NULL);
/* Create the full semaphore and initialize to 0 */
sem_init(&full, 0, 0);
/* Create the empty semaphore and initialize to BUFFER_SIZE */
sem_init(&empty, 0, BUFFER_SIZE);
/* Get the default attributes */
pthread_attr_init(&attr);
/* init buffer */
counter = 0;
}
/* Producer Thread */
void *producer(void *param) {
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* generate a random number */
item = rand();
/* acquire the empty lock */
sem_wait(&empty);
/* acquire the mutex lock */
pthread_mutex_lock(&mutex);
if(insert_item(item)) {
fprintf(stderr, " Producer report error condition\n");
}
else {
printf("producer produced %d\n", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal full */
sem_post(&full);
}
}
/* Consumer Thread */
void *consumer(void *param) {
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* aquire the full lock */
sem_wait(&full);
/* aquire the mutex lock */
pthread_mutex_lock(&mutex);
if(remove_item(&item)) {
fprintf(stderr, "Consumer report error condition\n");
}
else {
printf("consumer consumed %d\n", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal empty */
sem_post(&empty);
}
}
/* Add an item to the buffer */
int insert_item(buffer_item item) {
/* When the buffer is not full add the item
and increment the counter*/
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
}
else { /* Error the buffer is full */
return -1;
}
}
/* Remove an item from the buffer */
int remove_item(buffer_item *item) {
/* When the buffer is not empty remove the item
and decrement the counter */
if(counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
}
else { /* Error buffer empty */
return -1;
}
}
int main(int argc, char *argv[]) {
/* Loop counter */
int i;
/* Verify the correct number of arguments were passed in */
if(argc != 4) {
fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT>\n");
}
int mainSleepTime = atoi(argv[1]); /* Time in seconds for main to sleep */
int numProd = atoi(argv[2]); /* Number of producer threads */
int numCons = atoi(argv[3]); /* Number of consumer threads */
/* Initialize the app */
initializeData();
/* Create the producer threads */
for(i = 0; i < numProd; i++) {
/* Create the thread */
pthread_create(&tid,&attr,producer,NULL);
}
/* Create the consumer threads */
for(i = 0; i < numCons; i++) {
/* Create the thread */
pthread_create(&tid,&attr,consumer,NULL);
}
/* Sleep for the specified amount of time in milliseconds */
sleep(mainSleepTime);
/* Exit the program */
printf("Exit the program\n");
exit(0);
}
Your code seems correct, except that you don't have prototypes at the top for:
int insert_item(buffer_item item);
int remove_item(buffer_item *item);
I was able to run your program without getting a seg fault after adding those prototypes. Using rand() in a multithreaded app is somewhat dangerous though. When I ran the code with multiple producers, they were all sleeping the same random time and generating the same random item numbers.
/*Producer_consumer problem in c using semaphores and pthreads*/
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define RAND_DIVISOR 100000000
#define TRUE 1
typedef int buffer_item;
#define BUFFER_SIZE 5
/* The mutex lock */
pthread_mutex_t mutex;
/* the semaphores */
sem_t full, empty;
/* the buffer */
buffer_item buffer[BUFFER_SIZE];
/* buffer counter */
int counter;
pthread_t tid; //Thread ID
pthread_attr_t attr; //Set of thread attributes
void *producer(void *param); /* the producer thread */
void *consumer(void *param); /* the consumer thread */
void initializeData() {
/* Create the mutex lock */
pthread_mutex_init(&mutex, NULL);
/* Create the full semaphore and initialize to 0 */
sem_init(&full, 0, 0);
/* Create the empty semaphore and initialize to BUFFER_SIZE */
sem_init(&empty, 0, BUFFER_SIZE);
/* Get the default attributes */
pthread_attr_init(&attr);
/* init buffer */
counter = 0;
}
/* Producer Thread */
void *producer(void *param) {
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* generate a random number */
item = rand();
/* acquire the empty lock */
sem_wait(&empty);
/* acquire the mutex lock */
pthread_mutex_lock(&mutex);
if(insert_item(item)) {
fprintf(stderr, " Producer report error condition\n");
}
else {
printf("producer produced %d\n", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal full */
sem_post(&full);
}
}
/* Consumer Thread */
void *consumer(void *param) {
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* aquire the full lock */
sem_wait(&full);
/* aquire the mutex lock */
pthread_mutex_lock(&mutex);
if(remove_item(&item)) {
fprintf(stderr, "Consumer report error condition\n");
}
else {
printf("consumer consumed %d\n", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal empty */
sem_post(&empty);
}
}
/* Add an item to the buffer */
int insert_item(buffer_item item) {
/* When the buffer is not full add the item
and increment the counter*/
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
}
else { /* Error the buffer is full */
return -1;
}
}
/* Remove an item from the buffer */
int remove_item(buffer_item *item) {
/* When the buffer is not empty remove the item
and decrement the counter */
if(counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
}
else { /* Error buffer empty */
return -1;
}
}
int main(int argc, char *argv[]) {
/* Loop counter */
int i;
/* Verify the correct number of arguments were passed in */
if(argc != 4) {
fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT>\n");
}
int mainSleepTime = atoi(argv[1]); /* Time in seconds for main to sleep */
int numProd = atoi(argv[2]); /* Number of producer threads */
int numCons = atoi(argv[3]); /* Number of consumer threads */
/* Initialize the app */
initializeData();
/* Create the producer threads */
for(i = 0; i < numProd; i++) {
/* Create the thread */
pthread_create(&tid,&attr,producer,NULL);
}
/* Create the consumer threads */
for(i = 0; i < numCons; i++) {
/* Create the thread */
pthread_create(&tid,&attr,consumer,NULL);
}
/* Sleep for the specified amount of time in milliseconds */
sleep(mainSleepTime);
/* Exit the program */
printf("Exit the program\n");
exit(0);
}
when i compile this using gcc i get the following errors:
cse#cse-Not-Specified:~/11011P0519$ vi producer_consumer2.c
cse#cse-Not-Specified:~/11011P0519$ gcc producer_consumer2.c
/tmp/ccu6fydZ.o: In function `initializeData':
producer_consumer2.c:(.text+0x32): undefined reference to `sem_init'
producer_consumer2.c:(.text+0x4e): undefined reference to `sem_init'
/tmp/ccu6fydZ.o: In function `producer':
producer_consumer2.c:(.text+0xac): undefined reference to `sem_wait'
producer_consumer2.c:(.text+0x11d): undefined reference to `sem_post'
/tmp/ccu6fydZ.o: In function `consumer':
producer_consumer2.c:(.text+0x160): undefined reference to `sem_wait'
producer_consumer2.c:(.text+0x1d1): undefined reference to `sem_post'
/tmp/ccu6fydZ.o: In function `main':
producer_consumer2.c:(.text+0x2ef): undefined reference to `pthread_create'
producer_consumer2.c:(.text+0x32d): undefined reference to `pthread_create'
collect2: ld returned 1 exit status
and when i try using gcc -lpthreads i get
cannot find lpthreads.
How to fix this ?
You need to Link with -lrt or -pthread while using function from semphore.h
compile as below
gcc producer_consumer2.c -pthread
see man sem_init
I have the following code but the producer and consumer code don't appear. It just prints "Exit the program". It's like the consumer and producer functions are never executed. I don't understand why this is happening. Can anyone explain why?
The code is as follows:
/* buffer.h */
typedef int buffer_item;
#define BUFFER_SIZE 18
/* main.c */
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
/* #include "buffer.h" */
#define RAND_DIVISOR 100000000
#define TRUE 1
/* The mutex lock */
pthread_mutex_t mutex;
/* the semaphores */
sem_t full, empty;
/* the buffer */
buffer_item buffer[BUFFER_SIZE];
/* buffer counter */
int counter;
pthread_t tid; //Thread ID
pthread_attr_t attr; //Set of thread attributes
void *producer(void *param); /* the producer thread */
void *consumer(void *param); /* the consumer thread */
void initializeData()
{
/* Create the mutex lock */
pthread_mutex_init(&mutex, NULL);
/* Create the full semaphore and initialize to 0 */
sem_init(&full, 0, 0);
/* Create the empty semaphore and initialize to BUFFER_SIZE */
sem_init(&empty, 0, BUFFER_SIZE);
/* Get the default attributes */
pthread_attr_init(&attr);
/* init buffer */
counter = 0;
}
/* Producer Thread */
void *producer(void *param)
{
buffer_item item;
while(TRUE)
{
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* generate a random number */
item = rand();
/* acquire the empty lock */
sem_wait(&empty);
/* acquire the mutex lock */
pthread_mutex_lock(&mutex);
if (insert_item(item))
fprintf(stderr, " Producer report error condition\n");
else
printf("producer produced %d\n", item);
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal full */
sem_post(&full);
}
}
/* Consumer Thread */
void *consumer(void *param)
{
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* aquire the full lock */
sem_wait(&full);
/* aquire the mutex lock */
pthread_mutex_lock(&mutex);
if (remove_item(&item)) {
fprintf(stderr, "Consumer report error condition\n");
} else {
printf("consumer consumed %d\n", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal empty */
sem_post(&empty);
}
}
/* Add an item to the buffer */
int insert_item(buffer_item item)
{
/* When the buffer is not full add the item
and increment the counter*/
if (counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
} else { /* Error the buffer is full */
return -1;
}
}
/* Remove an item from the buffer */
int remove_item(buffer_item *item)
{
/* When the buffer is not empty remove the item
and decrement the counter */
if (counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
} else { /* Error buffer empty */
return -1;
}
}
int main(int argc, char *argv[])
{
/* Loop counter */
int i;
/* Verify the correct number of arguments were passed in */
if(argc != 4) {
fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT>\n");
}
int mainSleepTime = atoi(argv[1]); /* Time in seconds for main to sleep */
int numProd = atoi(argv[2]); /* Number of producer threads */
int numCons = atoi(argv[3]); /* Number of consumer threads */
/* Initialize the app */
initializeData();
/* Create the producer threads */
for(i = 0; i < numProd; i++) {
/* Create the thread */
pthread_create(&tid,&attr,producer,NULL);
}
/* Create the consumer threads */
for(i = 0; i < numCons; i++) {
/* Create the thread */
pthread_create(&tid,&attr,consumer,NULL);
}
/* Sleep for the specified amount of time in milliseconds */
sleep(mainSleepTime);
/* Exit the program */
printf("Exit the program\n");
exit(0);
}
First you need to apply different tid's for your threads.
pthread_t tid1, tid2;
Then use these tid's:
pthread_create(&tid1, &attr, producer, NULL);
pthread_create(&tid2, &attr, consumer, NULL);
Lastly, skip the sleep and join the threads.
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
I've tested it, and works on my system. Below is the working code in full.
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include "buffer.h"
#define RAND_DIVISOR 100000000
#define TRUE 1
/* The mutex lock */
pthread_mutex_t mutex;
/* the semaphores */
sem_t full, empty;
/* the buffer */
buffer_item buffer[BUFFER_SIZE];
/* buffer counter */
int counter;
pthread_t tid1, tid2; //Thread ID
pthread_attr_t attr; //Set of thread attributes
void *producer(void *param); /* the producer thread */
void *consumer(void *param); /* the consumer thread */
void initializeData() {
/* Create the mutex lock */
pthread_mutex_init(&mutex, NULL);
/* Create the full semaphore and initialize to 0 */
sem_init(&full, 0, 0);
/* Create the empty semaphore and initialize to BUFFER_SIZE */
sem_init(&empty, 0, BUFFER_SIZE);
/* Get the default attributes */
pthread_attr_init(&attr);
/* init buffer */
counter = 0;
}
/* Producer Thread */
void *producer(void *param) {
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* generate a random number */
item = rand();
/* acquire the empty lock */
sem_wait(&empty);
/* acquire the mutex lock */
pthread_mutex_lock(&mutex);
if(insert_item(item)) {
fprintf(stderr, " Producer report error condition\n");
}
else {
printf("producer produced %d\n", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal full */
sem_post(&full);
}
}
/* Consumer Thread */
void *consumer(void *param) {
buffer_item item;
while(TRUE) {
/* sleep for a random period of time */
int rNum = rand() / RAND_DIVISOR;
sleep(rNum);
/* aquire the full lock */
sem_wait(&full);
/* aquire the mutex lock */
pthread_mutex_lock(&mutex);
if(remove_item(&item)) {
fprintf(stderr, "Consumer report error condition\n");
}
else {
printf("consumer consumed %d\n", item);
}
/* release the mutex lock */
pthread_mutex_unlock(&mutex);
/* signal empty */
sem_post(&empty);
}
}
/* Add an item to the buffer */
int insert_item(buffer_item item) {
/* When the buffer is not full add the item
and increment the counter*/
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
}
else { /* Error the buffer is full */
return -1;
}
}
/* Remove an item from the buffer */
int remove_item(buffer_item *item) {
/* When the buffer is not empty remove the item
and decrement the counter */
if(counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
}
else { /* Error buffer empty */
return -1;
}
}
int main(int argc, char *argv[]) {
/* Loop counter */
int i;
/* Verify the correct number of arguments were passed in */
if(argc != 4) {
fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT>\n");
}
int mainSleepTime = atoi(argv[1]); /* Time in seconds for main to sleep */
int numProd = atoi(argv[2]); /* Number of producer threads */
int numCons = atoi(argv[3]); /* Number of consumer threads */
/* Initialize the app */
initializeData();
/* Create the producer threads */
for(i = 0; i < numProd; i++) {
/* Create the thread */
pthread_create(&tid1,&attr,producer,NULL);
}
/* Create the consumer threads */
for(i = 0; i < numCons; i++) {
/* Create the thread */
pthread_create(&tid2,&attr,consumer,NULL);
}
/* Sleep for the specified amount of time in milliseconds */
//sleep(mainSleepTime);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
/* Exit the program */
printf("Exit the program\n");
exit(0);
}