0

I have a simple class with a variable (var1). The function of the class "changeVar" will be passed to pthread which will update the value. My question is when that thread is called inside a child and it updates the value after the child exits why does the value go back to the default which is 0. And how can I keep the updated value in the parent process if there is a way to do so.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <iostream> 
#include <random> 
#include <ctime>
#include <sys/wait.h>

class my_class
{
public: 
    int var1;
    my_class()
    {
        var1 = 0; 
    }
    void* changeVar() //change variable function thread will start execution from this function
    {
        this->var1 = 1; //the thread will then update the value
    }
    void print_var() //function to simply print the var1 variabel.
    {
        std::cout << "The value of var 1 = " << this->var1 << std::endl; 
    }
};

int main()
{
    typedef void* (*THREADFUNCPTR) (void* ); 
    my_class* my_class_ptr = new my_class();  // creating pointer to class that I will send to the thread.

    //forking a child; 
    if(fork() == 0)
    {
        pthread_t thread; 
        pthread_create(&thread, NULL, (THREADFUNCPTR) &my_class::changeVar, my_class_ptr); //creating thread
        pthread_join(thread, NULL); 
        my_class_ptr->print_var(); //on this print call the value of var1 printed is 1
        exit(0);
    } 
    else
    {
        wait(NULL);
        
        my_class_ptr->print_var(); //on this print call the value of var1 is 0

    }
}   

1 Answers1

3

Parent and child processes are completely independent processes. The thread executes in the child process, and, as such, the parent process has no knowledge of it.

A fork() basically gives you an identical twin of the original process. That's your child process. At the point of the fork() they are identical twins, but they are completely independent processes.

The new process has its own memory, and its own my_class_ptr, that has nothing to do, whatsoever with the parent process.

So, when the child process terminates the parent process still has the same my_class_ptr that it did before the fork(). Nothing changed.

Additionally:

       pthread_create(&thread, NULL, (THREADFUNCPTR) &my_class::changeVar, my_class_ptr); //creating thread

This is technically undefined behavior. pthreads are not a part of the C++ standard. pthreads are an operating-system specific APIs that have no guarantees of C++ compatibility. A particular implementation might offer some kind of guarantees that invoking a class method, in this manner, via pthread_create might work, otherwise this is undefined behavior. You cannot expect any meaningful results in the child process either.

Proper C++ code uses C++'s std::thread, where a comparable invocation is defined behavior. You should reimplement this program using std::threads, pretty much as is.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • C++20 is shipped with `std::jthread`; dtor joins. I would use that one if available. – Red.Wave Apr 24 '22 at 16:02
  • The point about undefined behavior might be clarified. We don't ordinarily make that claim just because a call is made to a function that is not part of the C++ standard library. What is undefined here is more to do with `my_class::changeVar` not having C linkage and not having the signature that `pthread_create()` expects. The code seems to assume that these deficiencies will offset each other, and maybe they will, but *that's* where the undefined behavior comes in. – John Bollinger Apr 25 '22 at 18:43