C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 12-05-2009, 08:53 AM   #1
Registered User
 
Join Date: Feb 2009
Posts: 40
Multithreading, tbb, local variable problem

Hi all,
I Just have just getting started to use intels Threading Building Blocks, but it just took some minutes before I got some problem. If I am running the code below will m_type.size() always return 0 even if i am pushing new data in a second thread:

Code:
#include <string>
#include <iostream>
#include <boost/thread.hpp>
#include "tbb/concurrent_vector.h"


class Test
{
public:
	Test(tbb::concurrent_vector<std::string> & t)
		//: m_type(t) 
	{
	}
	void worker()
	{
		std::cout << "Producing now..";
		while(true)
		{	
			if(m_type.size() < 1000)
			{
				m_type.push_back(std::string("Mohaha"));
				std::cout << "worker: size = " << m_type.size() << std::endl;
			}
		}
	}

	void consumer()
	{
		std::cout << "Consuming now..";
		while(true)
		{
			std::cout << "Consumer: size = " << m_type.size() << std::endl;
			if(m_type.size())
			{
				std::string message = m_type.back();
				std::cout << "Message: " << message << std::endl;
				if(m_type.size() > 100)
				{
					m_type.clear();
				}
			}
		}
	}
private:
	tbb::concurrent_vector<std::string> m_type;
};


int main(int argc, char** argv)
{
	tbb::concurrent_vector<std::string> vec;
	Test test(vec);


	boost::thread thread(boost::bind(&Test::worker, test));
	boost::thread thread2(boost::bind(&Test::consumer, test));
	thread2.join();
	thread.join();
}
But if I am making m_type to a reference (&) will it work without problems.

I know that local variables can be read into a processor cache and that is what I think happens, but how do I prevent it? And if it isn't the problem, what I am doing wrong then?

I second question:
Do any of you have any good multi threading links to share?


Thanks in advance
idleman is offline   Reply With Quote
Old 12-05-2009, 11:21 AM   #2
Registered User
 
C_ntua's Avatar
 
Join Date: Jun 2008
Posts: 1,526
Can you post the exact output of the program?
C_ntua is offline   Reply With Quote
Old 12-05-2009, 12:00 PM   #3
Registered User
 
Join Date: Feb 2009
Posts: 40
Exactly? No, it is different every time I run it of course.

The program acts like it got 2 tbb::concurrent_vector<std::string> separated for each thread, even if it just got one. Even if the worker method pushes new data to the vector does the consumer never see it. It is like it is 2 different variables separated from each other. Worker thread says m_type.size() have size (x > 0) and consumer always 0. If I am in another way make m_type to a reference will it work, probably because the compiler cannot make some optimizes and if I am trying to make the variable of type volatile I just got compile errors.

I have search little and I probably need a memory barrier that force the processor to clean its L1/L2 cache and register every time, but I always have used boost::mutex before this so I don't really know how I fix it. I could add a mutex (mutex force memory barrier as I know), but what should be the point to use a concurrent container then?
idleman is offline   Reply With Quote
Old 12-05-2009, 12:07 PM   #4
Malum in se
 
abachler's Avatar
 
Join Date: Apr 2007
Posts: 3,188
You need to use critical sections to prevent simultaneous access to a modifiable object.
__________________
Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.
abachler is offline   Reply With Quote
Old 12-05-2009, 12:16 PM   #5
Registered User
 
Join Date: Feb 2009
Posts: 40
What do you mean? It is a concurrent container, it is thread safe to access from multiple threads, both read and write it says in the documentation.
idleman is offline   Reply With Quote
Old 12-06-2009, 03:08 PM   #6
Cat without Hat
 
CornedBee's Avatar
 
Join Date: Apr 2003
Posts: 8,579
Give Test a private copy constructor, and you'll see the problem (or not, given bind's error messages): Boost.Bind binds its arguments as copies. In other words, each of these threads has its private Test object, with its own private vector. You need to bind by reference, which you can achieve by using Boost's reference_wrapper:
Code:
	boost::thread thread(boost::bind(&Test::worker, boost::ref(test)));
	boost::thread thread2(boost::bind(&Test::consumer, boost::ref(test)));
__________________
All the buzzt!
CornedBee

"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
CornedBee is offline   Reply With Quote
Old 12-06-2009, 03:30 PM   #7
Registered User
 
Join Date: Feb 2009
Posts: 40
Thanks CornedBee, I never thought about it
idleman is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Variable Allocation Problem bavetta C Programming 3 11-14-2009 12:52 AM
Problem when trying to return union type variable from function limp C Programming 3 10-13-2009 08:49 AM
VERY strange problem. My program hangs unless I add a test variable and never use it. rasheemo C Programming 2 10-10-2009 10:38 PM
Warning : returns address of a local variable YET correct output tapti C Programming 5 08-14-2009 03:15 AM
Need some help... darkconvoy C Programming 32 04-29-2008 03:33 PM


All times are GMT -6. The time now is 12:09 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22