jeudi 13 juillet 2017

Problems with references using variable number of std::thread

I have use posix threads (pthread) but I am giving a try to standard C++11 thread (which most likely is also pthread underneath). I have gone several posts here and other forums but I could not figure out my problem. I would love if someone can give a light.

The problem is that I am trying to pass data to threads, that modify the data inside and the modification must be seen by the main thread after the thrown threads are finished (joined). The problem is that in some threads the data (an int) is not read correctly, thus the output result is not correct.

The minimal code I could write to replicate the problem is:

#include <iostream>
#include <vector>
#include <thread>

using namespace std;

void threadCallbackInt(int const & x)
{
    int & y = const_cast<int &>(x);
    y += 10;
    std::cout<<"Inside Thread x = "<<y << " at position = " << &y <<std::endl;
}

int main(int argc, char* argv[])
{
    unsigned int nthreads = 3;
    vector<int> ints;
    vector<std::thread> threads(nthreads);
    threads.reserve(nthreads);
    for(unsigned int i = 0; i < nthreads; i++){
        ints.push_back(i);

        std::cout<<"In Main Thread : Before Thread Start x = "<<ints.at(i)<< " at position = " << &ints.at(i) << std::endl;
        threads[i] = std::thread(threadCallbackInt,std::ref(ints[i]));
    }

    cout << "size = " << threads.size() << endl;

    for(unsigned int i = 0; i < nthreads; i++){
        threads[i].join();
    }

    for(unsigned int i = 0; i < nthreads; i++){
        std::cout<<"In Main Thread : After Thread Start x = "<<ints[i]<< " at position = " << &ints[i] << std::endl;
    }
    return 0;
}

There are several similar posts over several forums, but the one that I think that is the closet to my problem is the one at C++ 11 std::thread strange behavior

Note that I use the method reserve in order to avoid reference invalidation and the number, but with no avail.

Depend on the execution, I get different outputs. This is one of the outputs:

In Main Thread : Before Thread Start x = 0 at position = 0x21d7c40

In Main Thread : Before Thread Start x = 1 at position = 0x21d81e4

In Main Thread : Before Thread Start x = 2 at position = 0x21d7c48

Inside Thread x = 10 at position = 0x21d81e4

size = 3

Inside Thread x = 12 at position = 0x21d7c48

Inside Thread x = 10 at position = 0x21d7c40

In Main Thread : After Thread Start x = 10 at position = 0x21d7c40

In Main Thread : After Thread Start x = 1 at position = 0x21d7c44

In Main Thread : After Thread Start x = 12 at position = 0x21d7c48

Note that one of the x's is still not updated, even after the thread is finished. This is because the memory that was used for that is not the correct one (before the thread it is 0x21d81e4, and after it is 0x21d7c40). If you run the code, you will see that the results ill be different, and any time that a reference mismatch, I get the wrong result.

Any light regarding a possible solution will be very welcome. Sorry if this post is duplicate (I could not find a actual answer for this exact problem). But if it is, please, indicate the original post.

Aucun commentaire:

Enregistrer un commentaire