Solved

Does my thread need volatile variables?

Posted on 2004-08-13
7
206 Views
Last Modified: 2011-09-20
I have a program that collects packets and stores info in a binary search tree. Every 5 minutes, I want to dump the tree to file and then repopulate with new packets. So, after I dump, I clear out the BST. My application uses libpthread. My BST is in global space, so that both threads can see it (one thread to collect, and one to dump to file).  When I don't clean up the tree, and just let it keep accumulating, the tree is fine, but when I delete and then start adding anew, the tree gets duplicates in it quite often. The function that clears the tree seems to work just fine. Could gcc 3.3.3 be pulling my leg with its optimzers and should I make my BST volatile?

This is my first program using threads and I'm not very good at debugging with threads at all.

going nuts,
      ryan
0
Comment
Question by:dignified
7 Comments
 
LVL 23

Accepted Solution

by:
Mysidia earned 168 total points
ID: 11798768
If the value of some local variable is to be modified by something external like that concurrently executing process, then yes,
that should be marked volatile

You also may need to enforce mutual exclusion when you are modifying the tree
(i.e. only one thread is modifying the tree at any given time, and no other thread
is trying to read the tree while a different one is removing from it or reading from it)

I don't know how you have it arranged, but it could be that for example, when one thread is trying
to empty the tree, another thread collects a new element and re-write parts of it, undoing some of the
remover thread's work



0
 

Author Comment

by:dignified
ID: 11799134
I am using mutexes also. I lock the tree before doing any operation on it, and still the odd behavior. Right now my variables are defined in global space, outside any functions. All references in functions are via pointers.
0
 

Author Comment

by:dignified
ID: 11802671
seems I found the bug, it was in my delete. A long story with something odd happening in my implementation. Thankfully, as far as I can tell right now, it does not involve a race condition. What is the best way to debug realtime threads anyways?
0
 
LVL 22

Assisted Solution

by:NovaDenizen
NovaDenizen earned 166 total points
ID: 11810333
No joke, use many printfs.  It's pretty much impossible to reliably reproduce the timing that causes intermittent bugs in multithreaded programs, especially within a debugger.  Even using printfs can change the timing so that bugs stop happening (look up the "Heisenbug principle").  Closely follow a log and your understanding of your code will improve, which should help you sleuth out what is going wrong.

When writing multithreaded programs it's important to get your multithreaded basics right the first time and have a solid design that is both timing-proof and adequate for your needs.  
0
 
LVL 2

Assisted Solution

by:aleric
aleric earned 166 total points
ID: 12032136
No, volatile has to do with optimizations.

Suppose you have this code:

int* x = f();

int k = *x;
m = 3;
m += *x;

Then the compiler knows that no memory content was
changed by the 'm = 3' line (or whatever code is there),
and therefore that it is impossible that the value of *x
has changed: both 'x' as well and ANY memory did
not change.  It is therefore allowed to optimize this
code by storing the value of *x in a temporary (or
just reusing k):

int k = *x;
m = 3;
m += k;

Volatile now has the following meaning.  If you declare

int volatile* x = f();

Then the compiler is not allowed anymore to assume
that that value remains unchanged - even if it normally
would assume this because the code that it is generating
itself doesn't change the value.

If you use threads, and do not use locking, then it is true
that the value of *x could be changed by another thread.
But that is not what volatile is intended for.  You should
instead use proper locking.  For example:

lock_for_x();   // pseudo code
int k = *x;
m = 3;
m += *x;
unlock_for_x();  // pseudo code

If the other threads also use the same lock before
accessing whatever 'x' might point to (ie, some array
of ints with a fixed size) - then you garanteed that
indeed *x wasn't changed by another thread; and
the normal optimization is allowed: no volatile
needed.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
This video discusses moving either the default database or any database to a new volume.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now