C++ UNIX threading

I am doing a project with threading in UNIX and C++. Basically there is a producer thread, and 5 consumer threads. The producer thread adds incrementing numbers into a queue at random times, and the consumer threads poll the q trying to remove it. For some reason my q.size() keeps going negative and i cant figure out why.

 #include <queue>
 #include <list>

 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>

 using namespace std;

 #define NUM_CONSUMER_THREADS 5
 #define NUM_PRODUCER_THREADS 1
 #define BUFFER_SIZE 20

 void *c_thread_function(void *arg);
 void *p_thread_function(void *arg);

 queue<int> q;

 int produce(int cur)
 {
  int temp = cur + 1;
  return temp;
 }

 void append(int num)
 {
  if ( q.size() < BUFFER_SIZE )
  {
   q.push(num);
  }
 }

 int take()
 {
  int removed = q.front();
  q.pop();
  sleep(1);
  return removed;
 }

 void consume(int num, int thread)
 {
  printf("%d consumed %d \n", thread, num);
 }


 int main() 
 {
  int result;

  pthread_t cthreads[NUM_CONSUMER_THREADS];
  pthread_t pthreads[NUM_PRODUCER_THREADS];

  void *thread_result;

  // build an array of consumer threads
  for(int num_of_cthreads = 0; num_of_cthreads < NUM_CONSUMER_THREADS; num_of_cthreads++) 
  {
   result = pthread_create(&(cthreads[num_of_cthreads]), NULL, c_thread_function, (void *)num_of_cthreads);
   if ( result != 0 )
   {
    perror( "Thread Creation Failed");
    exit(EXIT_FAILURE);
   }
   //sleep(1);  
  } 

  // build an array of producer threads
  for(int num_of_pthreads = 0; num_of_pthreads < NUM_PRODUCER_THREADS; num_of_pthreads++) 
  {
   result = pthread_create(&(pthreads[num_of_pthreads]), NULL, p_thread_function, NULL);
   if ( result != 0 )
   {
    perror( "Thread Creation Failed");
    exit(EXIT_FAILURE);
   }
   //sleep(1);  
  }

  printf("All threads created\n");
  while ( true )
  {
   // do nothing
  }
 }

 void *c_thread_function(void *arg)
 {
  int temp = (long)arg;
  printf("Consumer thread %d created \n", temp);

  while ( true )
  {
   while (  q.size() > 0 )
   {
    int w = take();
    consume(w, temp);
    printf(" q size is now %d \n", q.size());
   }
  }
 }

 void *p_thread_function(void *arg) 
 {
  printf("Producer thread created \n");

  int itemsAdded = 0;
  int temp;
  int sleepTime;

  while ( true ) 
  {
   while ( q.size() < BUFFER_SIZE )
   {
    temp = produce(itemsAdded);

    sleepTime = 1+(int)(9.0*rand()/(RAND_MAX+1.0));
    sleep(sleepTime);

    append(temp);

    printf("Producer adds: %d \n", temp);
    printf(" q size is now %d \n", q.size());

    itemsAdded++;
   }
  }
 }

Output:

Producer adds: 1

q size is now -1

0 consumed 1

q size is now -2

1 consumed 1

q size is now -3

3 consumed 1

q size is now -4

4 consumed 0

q size is now -5

0 consumed 0

Answers


You need to learn about the concept of race conditions and mutual exclusion. Your std::queue object is a shared resource, meaning that more than one thread is operating on it - potentially at the same time. That means you have to protect it using locks (known as mutexes), so that each access is synchronized. Otherwise, you'll get what's known as a race condition, where one thread modifies data while another thread is also accessing/modifying the data, leading to an inconsistent or corrupt program state.

To prevent race conditions, you need to lock a pthread_mutex object before every queue access.

First, you need to create a mutex object and initialize it.

pthread_mutex mymutex;
pthread_mutex_init(&mymutex, 0);

Your application code should then look something like this:

pthread_mutex_lock(&mymutex);

// Do something with queue

pthread_mutex_unlock(&mymutex);

When one thread acquires the lock, no other thread can acquire the lock. A thread that tries to acquire a lock that has already been acquired by another thread will simply wait until the lock is released. This synchronizes access to the queue, ensuring that only one thread modifies it at a time.


Need Your Help

jQuery: Highlight link that have the same href as another

javascript jquery href

I'm working on a project, where I want to highlight the link (in a menu) that has the same href as another link on the site (in .container).

mongoDB references fetching takes time

mongodb optimization pymongo mongoengine

I use mongoengine as Object-Document mapper. Here is a brief description of the collections that are causing the problem. Each document in collection A, can have a list of references to documents in

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.