c++referencepthreadspthread-key-create

pthread does not see instance variable passed as argument


I have a class in C++ that uses boost python. I am trying to run python code in a thread from C++ using pthread. The problem is that the code below isn't producing any output. I was expecting an output John DOE in stdout. It seems that &this->instance doesn't carry the values that are being set inside the object. How can I pass current object or its instance variable to the pthread_create so that pthread can see what is being passed?

Python:

class A: 
  def __init__(self, name): 
      self.name = name

  def printName(self, lastName): 
      print self.name + " " + lastName

C++:

#include <boost/python.hpp>
#include <string.h>
#include <pthread.h>

using namespace std;
using namespace boost::python;

class B {
    public:
        object instance;
        B();
        void setupPython();
        static void *runPython(void *);
};

B::B() {
    Py_Initialize();
}

void B::setupPython() {
    pthread_t t1;
    try {
        object a = import("A");
        instance = a.attr("A")("John");
        pthread_create(&t1, NULL, runPython, &this->instance); // THIS IS PROBLEM
    }
    catch(error_already_set const &) {
        PyErr_Print();
    }
}

void *B::runPython(void *instance) {
    ((object *)instance)->attr("printName")("DOE");
}

int main() {
    B b;
    b.setupPython();
}

Thank you.


Solution

  • The problem is:

    int main() {
        B b;
        b.setupPython(); // You create a thread here
        // But here, b is destroyed when it's scope ends
    }
    

    The code in your thread is not guaranteed to run before b is freed.

    Try allocating b on the heap and check if it works:

    int main() {
        B* b = new B();
        b->setupPython();
        // also, you should add a call to pthread_join
        // here to wait for your thread to finish execution.
        // For example, changing setupPython() to return the
        // pthread_t handle it creates, and calling pthread_join on it.
    }