Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

POSIX Thread. Why is the producer-consumer program terminated?

I tried to write a simple C producer-consumer program using POSIX Thread, a library for working with threads.

The code has a global queue from where threads exchange information. The queue has been tested and should work correctly. There are also two threads involved:

Producer. Generates a random number and puts it in a queue;
Consumer. Retrieves a number from the queue and prints it to the screen.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

main.c:


#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include "queue.h"

pthread_mutex_t mutex;
pthread_cond_t pcond;
pthread_cond_t ccond;

static const unsigned int X = 10;

void* producer(void* args)
{
    for (int i = 0; i < X; i++)
    {
        pthread_mutex_lock(&mutex);
        while (queue_is_full())
            pthread_cond_wait(&pcond, &mutex);
        if (queue_is_empty())
            pthread_cond_signal(&ccond);
        queue_enqueue(rand() % (9999 + 1 - 0) + 0);
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

void* consumer(void* args)
{
    for (int i = 0; i < X; i++)
    {
        pthread_mutex_lock(&mutex);
        while (queue_is_empty())
            pthread_cond_wait(&ccond, &mutex);
        if (queue_is_full())
            pthread_cond_signal(&pcond);
        printf("%i", queue_dequeue());
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main(void)
{
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&pcond, NULL);
    pthread_cond_init(&ccond, NULL);
    
    pthread_t thProducer, thConsumer;
    pthread_create(&thProducer, NULL, producer, NULL);
    pthread_create(&thConsumer, NULL, consumer, NULL);
    
    pthread_join(thProducer, NULL);
    pthread_join(thConsumer, NULL);
    return 0;
}

This program terminates upon startup. The message Application.exe has stopped working. is issued by the system immediately after starting the program. How can I fix the program?

queue.c:

#include "queue.h"
 
#define CAPACITY 2048
 
static int* queue;
static int head;
static int tail;
 
void queue_init()
{
    queue = malloc(CAPACITY * sizeof(int));
    head = -1;
    tail = 0;
}
 
void queue_enqueue(int value)
{
    if (queue_is_full())
        exit(1);
    queue[tail] = value;
    if (head == -1)
        head = 0;
    if (tail == CAPACITY - 1)
        tail = 0;
    else
        tail++;
}
 
int queue_dequeue()
{
    if (queue_is_empty())
        exit(1);
    int item = queue[head];
    if (head != CAPACITY - 1)
        head++;
    else
        head = 0;
    if (head == tail)
    {
        head = -1;
        tail = 0;
    }
    return item;
}
 
bool queue_is_full()
{
    return head == tail;
}
 
bool queue_is_empty()
{
    return head == -1;
}
 
int queue_size()
{
    if (head != -1)
    {
        return head < tail ? tail - head : (CAPACITY - head) + tail;
    }
    return 0;
}

>Solution :

gcc’s -fsanitize=address finds the direct problem immediately (and so should any debugger).

AddressSanitizer:DEADLYSIGNAL
=================================================================
==1==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000401436 bp 0x7fbd0f7fde40 sp 0x7fbd0f7fde30 T2)
==1==The signal is caused by a READ memory access.
==1==Hint: address points to the zero page.
    #0 0x401436 in queue_dequeue /app/example.c:56
    #1 0x401596 in consumer /app/example.c:99
    #2 0x7fbd139c4608 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8608)
    #3 0x7fbd138e9162 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f162)

So it’s a NULL pointer dereference at this line:

int item = queue[head];

queue is initialized by queue_init …which is never called.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading