5

I have a program which runs two different operations and i'd like to share variables between them.

At the moment, i'm using threads instead of fork processes but i'm having problems in sharing variables even if I declared them as volatile.

I tried with boost doing:

boost::thread collisions_thread2(boost::bind(function_thread2);

by declaring the shared variables as volatile, but it seems that function_thread2() function is not able to see changes on the shared variables.

What i'd like to do is something like:

thread1:

while(true){
//..do somet stuff
check variable1
}

thread2:

while(true){
do some other stuff
check and write on variable1
}

Can you suggest me a tutorial or a method to easily share variable between threads? May be boost library can be useful in this case? Do you think it's better to use fork()?

I know that i have to use mutex in order to avoid critical situations, but i never used it.

Marcus Barnet
  • 2,083
  • 6
  • 28
  • 36
  • Check if [this question](http://stackoverflow.com/questions/118199/c-thread-shared-data) helps. And ultimately [Boost Thread Synchronization](http://www.boost.org/doc/libs/1_49_0/doc/html/thread/synchronization.html) – jweyrich Feb 29 '12 at 19:11
  • volatile has nothing to do with threads – BЈовић Feb 29 '12 at 19:12
  • You don't even need `volatile` to share variables. Global variables are shared by default. But this is kind of a bad thing since it makes creating data races easy. When you have data races you can't expect your program to behave reasonably, so you're probably running into some variety of this. You'll need to post more of your real code to get help diagnosing data races. – bames53 Feb 29 '12 at 19:16
  • @bames53 Yes you don't need volatile but it's good practice to use it in Multithreaded programs to avoid bugs due to compiler optimizations. – Sid Feb 29 '12 at 19:25
  • @Sid I'm not too familiar with this, but I think as long as you avoid data races you get sequential consistency without using `volatile`. Maybe `volatile` is still needed to guarantee that a thread makes progress though. – bames53 Feb 29 '12 at 19:56
  • @bames53 I was also taken by surprise when I had first learned about this. It was a bit mind-boggling to think that a perfectly well synchronized block of code could create MT issues due to compiler optimizations. But it can happen (read this article http://drdobbs.com/cpp/184403766) – Sid Feb 29 '12 at 20:11
  • @Sid In the code in that article `while (!flag_)` creates a data race whether `flag_` is volatile or not. – bames53 Feb 29 '12 at 20:35
  • @bames53 I believe that's the author's oversight on that particular example. I think he/she assumed that the while loop is inside a critical section. The examples further down using LockingPtr are correct. – Sid Feb 29 '12 at 20:39
  • @Sid Volatile is probably still needed, but I'm not sure how much of that is handed for you, e.g., inside `std::atomic`, and I'm not sure how much non-standard memory models still apply how that C++ has a defined memory model. The above example is just to illustrate that code that was right before isn't necessarily right under the new model. – bames53 Feb 29 '12 at 20:51
  • @bames53 Hmm I've never used std::atomic before... – Sid Feb 29 '12 at 21:24

3 Answers3

2

If using the posix threading libs (which I recommend) then use pthread_mutex_t.

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

Then, in each thread when you want to synchronize data access:

pthread_mutex_lock(&lock);
//access the data
pthread_mutex_unlock(&lock);
Jonathan Henson
  • 8,076
  • 3
  • 28
  • 52
2

If you can use boost, you can use boost::mutex.

// mtx should be shared for all of threads.
boost::mutex mtx;

// code below for each thread
{
  boost::mutex::scoped_lock lk(mtx);
  // do something
}
kamae
  • 1,825
  • 1
  • 16
  • 21
1

any kind of mutex lock or unlock would work. As far as your question on volatile goes, this keyword is a good practice especially in multi-threaded programs such as yours. But it doesn't affect the way you lock and unlock. volatile simply tells the compiler not to optimize a variable for e.g. by putting it in a register. Here's a very good explanation:

http://drdobbs.com/cpp/184403766

Sid
  • 7,511
  • 2
  • 28
  • 41