Thread: Accessing Variables from another thread.

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    84

    Accessing data from another thread.

    Hi,

    I have an application which needs to access data from another thread but I'm not sure how to handle this. I am explaining this in terms of physics objects which my application has but there other cases like this as well so its not a physics problem.

    Basically I have a physics object class which is part of the private implementation and a physics object user class which acts a wrapper to the private implementation. The user only sees the wrapper class and does not know about the existence of the internal class or what it does. The internal class has some functions which compute its state, such as gravity acceleration mass etc. The problem is that I want the user to be able to query those variables. Some variables are constant (eg: mass) however some of them are dynamic and need to be computed every time the simulation updates on its own thread (eg: acceleration). This computation can only be done when the physics thread is allowed to run, but the user can potentially create and call functions on the wrapper class from anywhere and these should not cause any problems. This works when the user is trying to set data as the wrapper class buffers it up until the thread is allowed to run, but I am not sure how the user can get the data at any time ?

    eg:
    ---public---
    Code:
    class PhysicsObjectUser
    {
    public:
      float GetGravity(); //can be called at any time from the client side application, how do i handle this ?
    
      void ApplyForce(float amt);//this is buffered up until the physics thread is entered and then the corresponding function in the internal interface is called.
    }
    ---private---
    Code:
    class PhysicsObjectInternal
    {
    public:
      float ComputeGravity(); //can only be called when the physics thread is entered
    }
    How can I give the user its data instantly without having them worry about threading issues. I am open to redesigning my interface so if there are existing solutions to this kind of problem, let me know. I was thinking of caching the variables in the wrapper class and then fill them up every time the physics step runs but there are too many variables and this will increase the size of the wrapper class significantly and perhaps decrease performance.

    Any ideas ?
    Thanks!
    Last edited by rocketman03; 09-03-2011 at 11:16 PM.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    With concurrent access, you have to have synchronization. The goal is to minimize concurrent access. Acquiring a lock is cheap. What's expensive is two or more threads acquiring a lock at the same time.

    It sounds like you just have 2 threads the want access to the data, in which case you could just use a mutex to provide synchronized access. If there were multiple threads that want read access, then a read-write lock may be appropriate.

    gg

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    84
    Yes, that is correct. There are only two threads at the moment. The physics thread acquires a lock before it performs the simulation. The problem is that I don't want the user to acquire a lock or deal with threading issues. These wrapper objects can be created from anywhere in the application code and then the core code checks the user classes to see if they want to update the state once it acquires the lock. The only problem is that I can't find a reasonable way for the client code to read the current state of the internal objects without dealing with synchronization issues. The main reason for these wrapper objects was to allow user code to be relatively simple and let the internal representation deal with locks and threading issues etc. Is there a common way of handling this issue ?

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You need to provide an API (possibly class interface) for use by the user. Within the implementation of function in that API, provide suitable synchronisation, hide back end data structures, etc etc.

    Keep in mind that no object can safely synchronise access to itself. However, an object A can synchronise access to another object B using (for example) a mutex M, as long as no code accesses directly object B or mutex M by any means other than by using operations of object A.

    More generally, you need to decide how strong you want your guarantees to be (for example, what rules can you be sure users will obey?). If you want guarantees of such things (i.e. you can't trust user code not to do things it shouldn't) you cannot expose any objects directly to your user code. You may need to copy data into proxy structures, copy data by value, use programming techniques (eg pimple idiom aka compilation firewall) to hide implementation details from your user code.

    Locks, incidentally, are not generally cheap. You need to structure your code so you use locks as little as possible to achieve required synchronisation.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    84
    Thanks, I'll look into what you suggested a bit more. But as of now, I only acquire a lock once and do all the processing then. I intended to keep it like that, but this case is the only exception which is giving me a bit of trouble. The user has no direct access to the internals. The internal class keeps a pointer to the user class and queries its state for changes once it acquires a lock. I'm trying to structure the code in a way so that there is only 1 lock which needs to be acquired per update.

  6. #6
    ‡ †hë Ö†hÈr sîÐè ‡ Nor's Avatar
    Join Date
    Nov 2001
    Posts
    299
    If your only needing read access to the protected structers/classes, then let your reading thread get a mutex lock, pass it a copy of the information requested, then release the lock.
    Your reading thread will at times have outdated information. How outdated is entirly up to you.

    Say your useing this information to draw to the screen, you get a mutex lock to the information, then copy it and release the lock.
    You now have a snapshot of a time index, as you start your drawing code, the other thread is free to continue processing the next time index.

    anyway hop this helps, i found it a while back when i had a problem like this one.
    Code:
    #pragma once
    #ifndef _MUTEX_LOCK_H
    #define _MUTEX_LOCK_H
    #include <windows.h>
    
    class Mutex{	friend class Lock;
    public:    
    	Mutex () 
    	{ 
    		InitializeCriticalSection (& _critSection);
    	}    
    	
    	~Mutex () 
    	{ 
    		DeleteCriticalSection (& _critSection); 
    	}
    private:    
    	void Acquire ()    
    	{        
    		EnterCriticalSection (& _critSection);
    	}    
    
    	void Release ()
    	{
    		LeaveCriticalSection (& _critSection);
    	}    
    	CRITICAL_SECTION _critSection;
    };
    
    class Lock{
    public:    
    	// Acquire the state of the semaphore    
    	Lock ( Mutex & mutex )        
    		: _mutex(mutex)    
    	{
    		_mutex.Acquire();    
    	}    
    	// Release the state of the semaphore    
    	~Lock ()    
    	{
    		_mutex.Release();
    	}
    private:
    	Mutex & _mutex;
    };	
    
    
    
    class varablelock{
    public:
    	
    	//method to get Instance of class  
    	static varablelock *getInstance( void )  
    	{    
    		//Note that the class is only created when this method is called first time    
    		if(!instance_)
    			instance_ = new varablelock;
    		return instance_;
    	}  
    	
    	//method to delete Instance of class  
    	static void deleteInstance( void )  
    	{    
    		if(instance_)
    			delete instance_;
    		instance_ = NULL;
    		
    		//important as this can create dead reference problems  
    	}  
    	Mutex mutex_;
    	varablelock() {};  
    	~varablelock() {};  
    
    private:  
    	//variable to store the instance of singleton  
    	static varablelock *instance_;  
    	//default constructor should be private to prevent instantiation  
    	//destructor should be made private so no one can delete this accidently  
    	//We also need to prevent copy being created of the object  
    	varablelock(const varablelock&);  
    };
    #endif
    and to use it do something like this

    Code:
        varablelock output_lock;
        .....
        if( update_state ){
            Lock thread_safe( output_lock );
            //Mutex is locked on so we have sole access to data
            current_state = physic_engine.Copy(&time_index);
        }
        //mutex is destroyed after if statement
    Try to help all less knowledgeable than yourself, within
    the limits provided by time, complexity and tolerance.
    - Nor

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with Accessing Variables
    By vileoxidation in forum C++ Programming
    Replies: 10
    Last Post: 10-05-2009, 07:58 AM
  2. Accessing variables in a set individually.
    By Dontgiveup in forum C++ Programming
    Replies: 8
    Last Post: 04-21-2009, 05:31 PM
  3. accessing variables using structs
    By bazzano in forum C Programming
    Replies: 5
    Last Post: 04-25-2006, 11:09 AM
  4. accessing class variables
    By pug in forum C# Programming
    Replies: 3
    Last Post: 05-20-2005, 08:46 AM

Tags for this Thread