-1

I have a problem, I have this pointers in my thread code and they are being modify in there, but when it return to the main the changes are not there like this:

Threads

void threaded_function(Model_factory &mf, ppa::Node *root) { // threads management

try { // n try...

Main

 int main(int argc, char *argv[]) { ...

In the main I am creating a node root, then in threads the node is being given sequences and has a bool that changes to true like:

ppa::Node *root;

And in the threads is working (a thread group) I can get and set that bool as I wish, but when the thread group finishes with join all (this is boost) the pointer root give me 0 on this line

cout << root->has_sequence() << endl;

After this goes on and the node is again filled with something, so what I want to ask is why is my node pointer not reflecting the changes in the threads, is it design or am I wrong (likely the second) and what should I do a global root node will that fix my issue, but why?

Pedro.Alonso
  • 1,007
  • 3
  • 20
  • 41
  • 2
    Can you reduce it to a *minimal* but complete example that reproduces the problem perhaps? I'd try running and studying something smaller, but currently that's too big, missing a `main()` and dependent on external things we can't see. Have you tried running it in something like helgrind? – Flexo Jul 31 '12 at 06:57
  • yep I know is a lot, the problem is that I don't know where it is the race-cond, no I have not tried I will, nope since I don't know I don't think I can reduce it. – Pedro.Alonso Jul 31 '12 at 07:05
  • I have read it, but unfortunately with out knowing where is the cause I don't think I can. – Pedro.Alonso Jul 31 '12 at 07:06
  • the main is not needed it has a lot of thing extra, the threads are there. – Pedro.Alonso Jul 31 '12 at 07:07
  • This is a LOT of code. A multitude of thread checkers and analysers exists out there - just use one, e.g. Intel Thread Checker or Sun/Oracle Thread Analyzer. – Hristo Iliev Jul 31 '12 at 07:20
  • thanks I did not know those I will. (: – Pedro.Alonso Jul 31 '12 at 08:10

1 Answers1

1

If you have a race condition, you have to suspect that you are accessing critical sections unlocked. I notice that you are manually locking and unlocking your mutex variable. This could lead to errors in your code. For instance, this construct looks particularly alarming:

for (int i = 0; i < deque_done.size(); i++) {

    tuple_compare(deque_done.at(i));

    result_mutex.unlock();

}

Instead of locking and unlocking manually, you may consider using boost::recursive_mutex and boost::recursive_mutex::scoped_lock to manage lock acquisition and release.

boost::recursive_mutex result_mutex;

void foo () {
    boost::recursive_mutex::scoped_lock lock(result_mutex);
    //...
}

If you really insist on designing a recursive algorithm that allows reentrancy from multiple threads, perhaps you can make use of a boost::shared_mutex, and boost::shared_lock/boost::upgradeable_lock for the read lock, and boost::unique_lock/boost::upgrade_to_unique_lock for write access. You can follow this link for an example.

Community
  • 1
  • 1
jxh
  • 69,070
  • 8
  • 110
  • 193
  • how will that go, can you put a example of this. (: – Pedro.Alonso Jul 31 '12 at 08:00
  • @user1423656: I added a link for the `shared_mutex`, and a simple example for `recursive_mutex`. Regards – jxh Jul 31 '12 at 08:12
  • Well if anyone is interested it was this line, after putting it after for it works fine, thank you, like this for (int i = 0; i < deque_done.size(); i++) { tuple_compare(deque_done.at(i));} result_mutex.unlock(); . (: – Pedro.Alonso Jul 31 '12 at 13:51