Threading Segfault when reading members

43 views Asked by At

I am facing some problems when I am trying to read a class variable in my worker thread (That variable was not created withing that thread). Here is my class header with static worker thread function:

class C1WTempReader
{
public:
    C1WTempReader(std::string device);
    virtual ~C1WTempReader();

    void startTemRead();
    double& getTemperature();

private:
    std::string device;
    std::string path;
    double temperature;
    pthread_t w1Thread;
    std::mutex w1Mutex;


    bool fileExists(const std::string& filename);

    static void * threadHelper(void * arg)
    {
        return ((C1WTempReader*) arg)->tempReadRun(NULL);
    }

    void* tempReadRun(void* arg);
};

Here are the crucial methods I am using:

C1WTempReader::C1WTempReader(std::string device)
{
    path = W1_PATH + device + W1_SLAVE;
    if (!fileExists(path))
    {
        std::cout << "File " << path << " doesnt exist!" << std::endl;
        path.clear();
        return;
    }

    std::cout << "1 wire termometer device path: " << path << std::endl;
}

void C1WTempReader::startTempRead()
{
    if(pthread_create(&w1Thread, NULL, threadHelper, NULL) == -1)
    {
        std::cout << "1W thread creation failed" << std::endl;
    }
}

void* C1WTempReader::tempReadRun(void* arg)
{
    w1Mutex.lock(); // SEGFAULT
    std::string line;
    std::ifstream myfile (path.c_str());
    if (myfile.is_open())
    {
            while ( getline (myfile,line) )
            {
                    size_t found = line.find("t=");
                    if (found != std::string::npos)
                    {
                            found += 2;
                            std::string temp = line.substr(found, 10);
                            temperature = atof(temp.c_str());
                            temperature /= 1000;
                            std::cout << "Temperature: " << temperature << " *C" << std::endl;
                    }

                    line.clear();
            }
            myfile.close();
    }
    else
    {
        std::cout << "Unable to open file" << std::endl;
        temperature = 1000; // bad value
    }

    w1Mutex.unlock();
    return NULL;
}

double& C1WTempReader::getTemperature()
{

    if (pthread_join(w1Thread, NULL))
    {
        std::cout << "1W Unable to join thread!" << std::endl;
    }

    return temperature;
}

Segmentation fault happens in the tempReadRun method, as soon as I try to lock the mutex. I didnt have mutexes before and I noticed that it happens whenever I try to read any of the class variables that are created ruring the class creation and are not created within the new thread. What Am I doing wrong?

And heres how I am trying to run this:

string device = "28-00000713a636";
C1WTempReader tempReader(device);
tempReader.startTempRead();
.
.
.
double temp = tempReader.getTemperature();
2

There are 2 answers

0
Łukasz Przeniosło On

I have found what the problem was. In the function C1WTempReader::startTempRead():

if(pthread_create(&w1Thread, NULL, threadHelper, NULL) == -1)
{
     std::cout << "1W thread creation failed" << std::endl;
}

The last argument of pthread_create had to be changed to this.

0
MK. On

You are not passing argument to pthread_create:

if(pthread_create(&w1Thread, NULL, threadHelper, this) == -1)