Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Having different value for a global variable per thread.

Having different value for a global variable per thread.

Scheduled Pinned Locked Moved C / C++ / MFC
questiondatabaseregexlearning
9 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Code o mat
    wrote on last edited by
    #1

    Hello folks! I was just wondering, and thought i ask you, maybe some of you have nice ideas. So here's the deal: there is a static function i have to implement, but its declaration/definition has to match a certian predefined "form", i can write the implementation as i see fit but i can't change the number and types of parameters passed. Let's call this function: TheStaticFunction(). This is actually a callback function that gets called regularry while a 3rd party system is doing its processing. Now, if i want to pass some parameters to this method, i have to use some global variable(s), set them before letting the 3rd party processing begin, eg:

    int global_parameter_variable;

    void TheStaticFunction()
    {
    ... use value of global_parameter_variable as needed ...
    }

    ...
    void Do3rdPartProcessing()
    {
    global_parameter_variable = 123;
    Perform3rdPArtyProcessing();
    }

    This aproach works ok as long as i don't want to use multiple threads to do the processing but with different parameters per thread, since there's only one global global_parameter_variable. So my question is: what could be done to achieve this? One solution that comes to my mind is having some global object that stores the parameter values associated with thread handles. So when a thread is trying to use the 3rd party method, it stores its own parameter value associated with its own handle in this global object and inside the static method this global object is used to query the parameter value for the current thread. So something like this:

    CThreadedParameters globa_parameter_retriever;

    void TheStaticFunction()
    {
    ...
    int the_parameter = globa_parameter_retriever.GetParameterValueForThread(GetCurrentThreadHandle());
    ...
    }

    void Do3rdPartProcessing(int parameter)
    {
    globa_parameter_retriever.SetParameterValueForThread(GetCurrentThreadHandle(), parameter);
    Perform3rdPArtyProcessing();
    globa_parameter_retriever.RemoveParameterValueFor(GetCurrentThreadHandle());
    }

    Of course access to the globa_parameter_retriever would be properly synchronized. This method would probably work but you would have to perform a lookup based on the current thread's handle every time TheStaticFunction is called, althorough this is most likely now that much of an overhaul. So does anyone have any other idea or knows any other, simpler method that exists and i just don't know about it? This all is for now only hypothetical so i can't give you any test results. Thanks

    S J C R 4 Replies Last reply
    0
    • C Code o mat

      Hello folks! I was just wondering, and thought i ask you, maybe some of you have nice ideas. So here's the deal: there is a static function i have to implement, but its declaration/definition has to match a certian predefined "form", i can write the implementation as i see fit but i can't change the number and types of parameters passed. Let's call this function: TheStaticFunction(). This is actually a callback function that gets called regularry while a 3rd party system is doing its processing. Now, if i want to pass some parameters to this method, i have to use some global variable(s), set them before letting the 3rd party processing begin, eg:

      int global_parameter_variable;

      void TheStaticFunction()
      {
      ... use value of global_parameter_variable as needed ...
      }

      ...
      void Do3rdPartProcessing()
      {
      global_parameter_variable = 123;
      Perform3rdPArtyProcessing();
      }

      This aproach works ok as long as i don't want to use multiple threads to do the processing but with different parameters per thread, since there's only one global global_parameter_variable. So my question is: what could be done to achieve this? One solution that comes to my mind is having some global object that stores the parameter values associated with thread handles. So when a thread is trying to use the 3rd party method, it stores its own parameter value associated with its own handle in this global object and inside the static method this global object is used to query the parameter value for the current thread. So something like this:

      CThreadedParameters globa_parameter_retriever;

      void TheStaticFunction()
      {
      ...
      int the_parameter = globa_parameter_retriever.GetParameterValueForThread(GetCurrentThreadHandle());
      ...
      }

      void Do3rdPartProcessing(int parameter)
      {
      globa_parameter_retriever.SetParameterValueForThread(GetCurrentThreadHandle(), parameter);
      Perform3rdPArtyProcessing();
      globa_parameter_retriever.RemoveParameterValueFor(GetCurrentThreadHandle());
      }

      Of course access to the globa_parameter_retriever would be properly synchronized. This method would probably work but you would have to perform a lookup based on the current thread's handle every time TheStaticFunction is called, althorough this is most likely now that much of an overhaul. So does anyone have any other idea or knows any other, simpler method that exists and i just don't know about it? This all is for now only hypothetical so i can't give you any test results. Thanks

      S Offline
      S Offline
      sunlin7
      wrote on last edited by
      #2

      You can use the follow code: __declspec( thread ) int tls_i = 1; in visual c++.

      C 1 Reply Last reply
      0
      • C Code o mat

        Hello folks! I was just wondering, and thought i ask you, maybe some of you have nice ideas. So here's the deal: there is a static function i have to implement, but its declaration/definition has to match a certian predefined "form", i can write the implementation as i see fit but i can't change the number and types of parameters passed. Let's call this function: TheStaticFunction(). This is actually a callback function that gets called regularry while a 3rd party system is doing its processing. Now, if i want to pass some parameters to this method, i have to use some global variable(s), set them before letting the 3rd party processing begin, eg:

        int global_parameter_variable;

        void TheStaticFunction()
        {
        ... use value of global_parameter_variable as needed ...
        }

        ...
        void Do3rdPartProcessing()
        {
        global_parameter_variable = 123;
        Perform3rdPArtyProcessing();
        }

        This aproach works ok as long as i don't want to use multiple threads to do the processing but with different parameters per thread, since there's only one global global_parameter_variable. So my question is: what could be done to achieve this? One solution that comes to my mind is having some global object that stores the parameter values associated with thread handles. So when a thread is trying to use the 3rd party method, it stores its own parameter value associated with its own handle in this global object and inside the static method this global object is used to query the parameter value for the current thread. So something like this:

        CThreadedParameters globa_parameter_retriever;

        void TheStaticFunction()
        {
        ...
        int the_parameter = globa_parameter_retriever.GetParameterValueForThread(GetCurrentThreadHandle());
        ...
        }

        void Do3rdPartProcessing(int parameter)
        {
        globa_parameter_retriever.SetParameterValueForThread(GetCurrentThreadHandle(), parameter);
        Perform3rdPArtyProcessing();
        globa_parameter_retriever.RemoveParameterValueFor(GetCurrentThreadHandle());
        }

        Of course access to the globa_parameter_retriever would be properly synchronized. This method would probably work but you would have to perform a lookup based on the current thread's handle every time TheStaticFunction is called, althorough this is most likely now that much of an overhaul. So does anyone have any other idea or knows any other, simpler method that exists and i just don't know about it? This all is for now only hypothetical so i can't give you any test results. Thanks

        J Offline
        J Offline
        Jonathan Davies
        wrote on last edited by
        #3

        Would Thread Local Storage help http://msdn.microsoft.com/en-us/library/ms686812(VS.85).aspx[^]?

        C 1 Reply Last reply
        0
        • J Jonathan Davies

          Would Thread Local Storage help http://msdn.microsoft.com/en-us/library/ms686812(VS.85).aspx[^]?

          C Offline
          C Offline
          Code o mat
          wrote on last edited by
          #4

          That also looks good, thank you.

          > The problem with computers is that they do what you tell them to do and not what you want them to do. < > Sometimes you just have to hate coding to do it well. <

          1 Reply Last reply
          0
          • S sunlin7

            You can use the follow code: __declspec( thread ) int tls_i = 1; in visual c++.

            C Offline
            C Offline
            Code o mat
            wrote on last edited by
            #5

            Thank you, it looks very promising.

            > The problem with computers is that they do what you tell them to do and not what you want them to do. < > Sometimes you just have to hate coding to do it well. <

            1 Reply Last reply
            0
            • C Code o mat

              Hello folks! I was just wondering, and thought i ask you, maybe some of you have nice ideas. So here's the deal: there is a static function i have to implement, but its declaration/definition has to match a certian predefined "form", i can write the implementation as i see fit but i can't change the number and types of parameters passed. Let's call this function: TheStaticFunction(). This is actually a callback function that gets called regularry while a 3rd party system is doing its processing. Now, if i want to pass some parameters to this method, i have to use some global variable(s), set them before letting the 3rd party processing begin, eg:

              int global_parameter_variable;

              void TheStaticFunction()
              {
              ... use value of global_parameter_variable as needed ...
              }

              ...
              void Do3rdPartProcessing()
              {
              global_parameter_variable = 123;
              Perform3rdPArtyProcessing();
              }

              This aproach works ok as long as i don't want to use multiple threads to do the processing but with different parameters per thread, since there's only one global global_parameter_variable. So my question is: what could be done to achieve this? One solution that comes to my mind is having some global object that stores the parameter values associated with thread handles. So when a thread is trying to use the 3rd party method, it stores its own parameter value associated with its own handle in this global object and inside the static method this global object is used to query the parameter value for the current thread. So something like this:

              CThreadedParameters globa_parameter_retriever;

              void TheStaticFunction()
              {
              ...
              int the_parameter = globa_parameter_retriever.GetParameterValueForThread(GetCurrentThreadHandle());
              ...
              }

              void Do3rdPartProcessing(int parameter)
              {
              globa_parameter_retriever.SetParameterValueForThread(GetCurrentThreadHandle(), parameter);
              Perform3rdPArtyProcessing();
              globa_parameter_retriever.RemoveParameterValueFor(GetCurrentThreadHandle());
              }

              Of course access to the globa_parameter_retriever would be properly synchronized. This method would probably work but you would have to perform a lookup based on the current thread's handle every time TheStaticFunction is called, althorough this is most likely now that much of an overhaul. So does anyone have any other idea or knows any other, simpler method that exists and i just don't know about it? This all is for now only hypothetical so i can't give you any test results. Thanks

              C Offline
              C Offline
              Chris Losinger
              wrote on last edited by
              #6

              i've had good luck with this class:

              /*---------------------------------------------------------*/
              /*
              ** ThreadLocal.h - Thread Local Storage

              Written by Purush Rudrakshala,
              */

              #if !defined (__THREADLOCAL_H__)
              #define __THREADLOCAL_H__

              #include < list >

              class TlsException
              {
              public:
              explicit TlsException (DWORD error) : m_error (error) {}

              private:
              DWORD m_error;

              // not implemented
              TlsException ();
              };

              template < class T > class CISThreadLocal
              {
              public:
              explicit CISThreadLocal () : m_index (::TlsAlloc ())
              {
              if (m_index == ~0)
              {
              #ifdef _DEBUG
              throw TlsException (GetLastError ());
              #endif
              }

                // Initialize the critical section.
                InitializeCriticalSection(&g\_CritSection); 
              

              } // cons

              ~CISThreadLocal ()
              {
              if (m_index != ~0)
              {
              ::TlsFree (m_index);
              }

                m\_index = 0;
              
                // make sure no-one is playing with this data before we yank it away      
                EnterCriticalSection(&g\_CritSection); 
              
                // free thread local objects allocated for all threads
                for (std::list< T \*>::iterator it = m\_tsdList.begin(); it!=m\_tsdList.end(); it++)
                {
                    delete (\*it);
                }
              
                m\_tsdList.clear();
              
                // done
                LeaveCriticalSection(&g\_CritSection);
              
                // Delete the critical section.
                DeleteCriticalSection(&g\_CritSection);
              

              } // ~

              inline T* operator -> ()
              {
              return GetThreadLocal ();
              } // ->

              T* GetThreadLocal ()
              {
              T* tsd = 0;

                try
                {
                   if (m\_index != ~0) 
                   {
                      tsd = reinterpret\_cast (::TlsGetValue (m\_index));
                      if (tsd == 0) 
                      {
                         // thread local storage has not been allocated 
                         // for this thread yet, allocate an object and keep
                         // it in the list
                         tsd = new T;
                         BOOL success = ::TlsSetValue (m\_index, tsd);
                         if (!success)
                            throw TlsException (::GetLastError ());
              
                         EnterCriticalSection(&g\_CritSection); 
              
                         m\_tsdList.push\_back(tsd);
              
                         // done
                         LeaveCriticalSection(&g\_CritSection);
                      }
                   }
                }
                catch (...)
                {
                   tsd = NULL;
                }
              
                return tsd;
              

              } // GetThreadLocal

              ///////////////////////////////////////
              // have we allocated anything for this thread?

              bool HasTLS()

              C 1 Reply Last reply
              0
              • C Chris Losinger

                i've had good luck with this class:

                /*---------------------------------------------------------*/
                /*
                ** ThreadLocal.h - Thread Local Storage

                Written by Purush Rudrakshala,
                */

                #if !defined (__THREADLOCAL_H__)
                #define __THREADLOCAL_H__

                #include < list >

                class TlsException
                {
                public:
                explicit TlsException (DWORD error) : m_error (error) {}

                private:
                DWORD m_error;

                // not implemented
                TlsException ();
                };

                template < class T > class CISThreadLocal
                {
                public:
                explicit CISThreadLocal () : m_index (::TlsAlloc ())
                {
                if (m_index == ~0)
                {
                #ifdef _DEBUG
                throw TlsException (GetLastError ());
                #endif
                }

                  // Initialize the critical section.
                  InitializeCriticalSection(&g\_CritSection); 
                

                } // cons

                ~CISThreadLocal ()
                {
                if (m_index != ~0)
                {
                ::TlsFree (m_index);
                }

                  m\_index = 0;
                
                  // make sure no-one is playing with this data before we yank it away      
                  EnterCriticalSection(&g\_CritSection); 
                
                  // free thread local objects allocated for all threads
                  for (std::list< T \*>::iterator it = m\_tsdList.begin(); it!=m\_tsdList.end(); it++)
                  {
                      delete (\*it);
                  }
                
                  m\_tsdList.clear();
                
                  // done
                  LeaveCriticalSection(&g\_CritSection);
                
                  // Delete the critical section.
                  DeleteCriticalSection(&g\_CritSection);
                

                } // ~

                inline T* operator -> ()
                {
                return GetThreadLocal ();
                } // ->

                T* GetThreadLocal ()
                {
                T* tsd = 0;

                  try
                  {
                     if (m\_index != ~0) 
                     {
                        tsd = reinterpret\_cast (::TlsGetValue (m\_index));
                        if (tsd == 0) 
                        {
                           // thread local storage has not been allocated 
                           // for this thread yet, allocate an object and keep
                           // it in the list
                           tsd = new T;
                           BOOL success = ::TlsSetValue (m\_index, tsd);
                           if (!success)
                              throw TlsException (::GetLastError ());
                
                           EnterCriticalSection(&g\_CritSection); 
                
                           m\_tsdList.push\_back(tsd);
                
                           // done
                           LeaveCriticalSection(&g\_CritSection);
                        }
                     }
                  }
                  catch (...)
                  {
                     tsd = NULL;
                  }
                
                  return tsd;
                

                } // GetThreadLocal

                ///////////////////////////////////////
                // have we allocated anything for this thread?

                bool HasTLS()

                C Offline
                C Offline
                Code o mat
                wrote on last edited by
                #7

                Thank you.

                > The problem with computers is that they do what you tell them to do and not what you want them to do. < > Sometimes you just have to hate coding to do it well. <

                1 Reply Last reply
                0
                • C Code o mat

                  Hello folks! I was just wondering, and thought i ask you, maybe some of you have nice ideas. So here's the deal: there is a static function i have to implement, but its declaration/definition has to match a certian predefined "form", i can write the implementation as i see fit but i can't change the number and types of parameters passed. Let's call this function: TheStaticFunction(). This is actually a callback function that gets called regularry while a 3rd party system is doing its processing. Now, if i want to pass some parameters to this method, i have to use some global variable(s), set them before letting the 3rd party processing begin, eg:

                  int global_parameter_variable;

                  void TheStaticFunction()
                  {
                  ... use value of global_parameter_variable as needed ...
                  }

                  ...
                  void Do3rdPartProcessing()
                  {
                  global_parameter_variable = 123;
                  Perform3rdPArtyProcessing();
                  }

                  This aproach works ok as long as i don't want to use multiple threads to do the processing but with different parameters per thread, since there's only one global global_parameter_variable. So my question is: what could be done to achieve this? One solution that comes to my mind is having some global object that stores the parameter values associated with thread handles. So when a thread is trying to use the 3rd party method, it stores its own parameter value associated with its own handle in this global object and inside the static method this global object is used to query the parameter value for the current thread. So something like this:

                  CThreadedParameters globa_parameter_retriever;

                  void TheStaticFunction()
                  {
                  ...
                  int the_parameter = globa_parameter_retriever.GetParameterValueForThread(GetCurrentThreadHandle());
                  ...
                  }

                  void Do3rdPartProcessing(int parameter)
                  {
                  globa_parameter_retriever.SetParameterValueForThread(GetCurrentThreadHandle(), parameter);
                  Perform3rdPArtyProcessing();
                  globa_parameter_retriever.RemoveParameterValueFor(GetCurrentThreadHandle());
                  }

                  Of course access to the globa_parameter_retriever would be properly synchronized. This method would probably work but you would have to perform a lookup based on the current thread's handle every time TheStaticFunction is called, althorough this is most likely now that much of an overhaul. So does anyone have any other idea or knows any other, simpler method that exists and i just don't know about it? This all is for now only hypothetical so i can't give you any test results. Thanks

                  R Offline
                  R Offline
                  Russell
                  wrote on last edited by
                  #8

                  Coorect me if I wrong my interpretation: It looks that you have only to pass an input parameter of the threads. Well, in this case I think that the usual way is not to store the variable into the global memory but pass a pointer to the thread when it is starting. this pointer points to a struct where the new thread can find all the initial values. You have only to wait that the new thread read all the parameters and store they into his local memory, then the caller can continue the flow destroing the objects. If that parameters can be changed from the main thread during the execution you can then pass to every single thread a set of pointers to these variables. Of course you'll need to allocate an array of variable (one per each thread).


                  Russell

                  C 1 Reply Last reply
                  0
                  • R Russell

                    Coorect me if I wrong my interpretation: It looks that you have only to pass an input parameter of the threads. Well, in this case I think that the usual way is not to store the variable into the global memory but pass a pointer to the thread when it is starting. this pointer points to a struct where the new thread can find all the initial values. You have only to wait that the new thread read all the parameters and store they into his local memory, then the caller can continue the flow destroing the objects. If that parameters can be changed from the main thread during the execution you can then pass to every single thread a set of pointers to these variables. Of course you'll need to allocate an array of variable (one per each thread).


                    Russell

                    C Offline
                    C Offline
                    Code o mat
                    wrote on last edited by
                    #9

                    Thanks for the reply. Either i misunderstand you or you misunderstand me but if i am correct you are not talking about what i meant. I will try to explain with an example: Let's say you have a 3rd party library that performs some task, you can specify a pointer to a function for this 3rd party library and during its processing the library will call your specified function, for example to report progress. Let's say, this method has to have one parameter, an unsigned char that will change from 0 to 100 (percentage) as the 3rd party advances in the task.

                    void MyProgress(unsigned char percentage)
                    {
                    ...
                    }

                    ...
                    SetCallBackProcFor3rdPartyLib(MyProgress); //make the lib call MyProgress to report its progress
                    Do3rdPartyLibProcessing(); //make the lib do its magic
                    ...

                    Now, what if you would like to give other parameters to your MyProgress method, for example a handle to a control that should display the progress? You can't just do this:

                    void MyProgress(unsigned char percentage, HWND control)
                    {
                    ...
                    }

                    since the lib requires the method to take only one unsigned char parameter and nothing else. So what you can do to have a way for the MyProgress procedure to have access to this information (the handle) is to create a global variable, store this handle in this before you let the lib do the magic, and use this same variable inside MyProgress.

                    HWND the_control = NULL;

                    void MyProgress(unsigned char percentage)
                    {
                    CString str;
                    str.Format("%d %%", percentage);
                    SetWindowText(the_control, str);
                    }

                    ...
                    the_control = handle_of_the_control;
                    SetCallBackProcFor3rdPartyLib(MyProgress); //make the lib call MyProgress to report its progress
                    Do3rdPartyLibProcessing(); //make the lib do its magic
                    ...

                    This works, right? But if you have multiple threads all executing Do3rdPartyLibProcessing and all threads having their very own control to display the progress in, you can no longer use the same approach, since the_control exists only once in memory, so every executing thread would use this same memory when trying to store/retrieve their own control's window handle and bang, welcome to chaosland. So my original question is basicly: how to have a "thread level" global variable (so one that is unique per thread and can be accessed everywhere "inside" the thread). As the others said, TLS (Thread-Local Storage) seems to be just the answer for that. I hope this clears any misunderstandings, sorry if not.

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups