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

child thread does not see effect of increment by main thread

I am working with a C networking application using POSIX threading. I encountered a problem where a child thread serving as a monitor not detecting the change (increment) to a global counter made by the main thread. I managed to extract the relevant code into the following 3 files and reproduce the problem.

// common.h
#ifndef COMMON_H
#define COMMON_H
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/resource.h>
static volatile int glob = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void increment_clients_count();

#endif
// common.c
#include "common.h"

void increment_clients_count()
{
        // Lock
        pthread_mutex_lock(&mutex);     
        glob++;
        // Unlock
        pthread_mutex_unlock(&mutex);
}
// thread_incr_wrong.c 
// main function
#include "common.h"

void                    /* Loop 'arg' times incrementing 'glob' */
monitor()
{
    while(1)
    {        
        time_t current_time;
        time(&current_time);
        char *t = ctime(&current_time);
        if (t[strlen(t)-1] == '\n') t[strlen(t)-1] = '\0';
        printf("%s, Count : %d\n", t, glob);
        sleep(3);
    }

}


int
main(int argc, char *argv[])
{
    pthread_t t1;   
    int s;
   

    s = pthread_create(&t1, NULL, (void*)monitor, NULL);
    if (s != 0){
        perror("pthread_create");
        exit(1);
     }
    
    while(1){        
        increment_clients_count();        
        sleep(5);
    }

    
    exit(0);
}

When this cod runs, I hope to see

Tue Jan 11 18:56:24 2022, Count : 1
Tue Jan 11 18:56:27 2022, Count : 1
Tue Jan 11 18:56:30 2022, Count : 2
Tue Jan 11 18:56:33 2022, Count : 2
Tue Jan 11 18:56:36 2022, Count : 3
Tue Jan 11 18:56:39 2022, Count : 4
Tue Jan 11 18:56:42 2022, Count : 4
Tue Jan 11 18:56:45 2022, Count : 5
Tue Jan 11 18:56:48 2022, Count : 5
Tue Jan 11 18:56:51 2022, Count : 6
Tue Jan 11 18:56:54 2022, Count : 7

Instead, the output looks like this

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

Tue Jan 11 18:59:40 2022, Count : 0
Tue Jan 11 18:59:43 2022, Count : 0
Tue Jan 11 18:59:46 2022, Count : 0
Tue Jan 11 18:59:49 2022, Count : 0
Tue Jan 11 18:59:52 2022, Count : 0

The monitor thread did not see glob variable being incremented every 5 seconds.

Please let me know where in the code I did something wrong.

If you’d like to try reproduce the problem, you can copy those 3 files and build the executable with
cc -std=c99 -D_XOPEN_SOURCE=600 -D_DEFAULT_SOURCE -g -pedantic -Wall -W -Wmissing-prototypes -Wno-sign-compare -Wimplicit-fallthrough -Wno-unused-parameter -pthread -o thread_incr_wrong thread_incr_wrong.c common.c on any Linux machine. The executable’s name is thread_incr_wrong.

Thanks

>Solution :

Both glob and mutex are declared as static. This means that when common.h is included in both common.c and main.c, they each have their own copy of those variables.

Global variables should be declared in a header file where all source files can see them and defined in exactly one source file. So change what’s in the header to external declarations and put the definitions in common.c:

common.h:

extern volatile int glob;
extern pthread_mutex_t mutex;

common.c:

volatile int glob = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
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