1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Global variables between Threads

Discussion in 'C++' started by singh_r85, May 31, 2010.

  1. singh_r85

    singh_r85 New Member

    Joined:
    May 25, 2010
    Messages:
    19
    Likes Received:
    0
    Trophy Points:
    0
    I have a global variable "LampRadiance" that is being updated by thread #2, another thread (thread #1) uses this variable, are there any tricks in order to accomplish this task?

    When I run my program, my variable "LampRadiance" is equal to "0" (thread #2, doesn't seem to be updating this value?), yet my thread #1 function is doing some strange stuff (i.e. my if statement that evaluates "LampRadiance" > 0, is evaluating to true, even though the debugger is showing it as "0")?
     
  2. spoddar66

    spoddar66 New Member

    Joined:
    May 25, 2010
    Messages:
    23
    Likes Received:
    0
    Trophy Points:
    0
    declare LampRadiance as volatile. This makes sure that the processor isn't caching the variable.

    example :
    Code:
    long volatile LampRadiance;
     
  3. mmondal71

    mmondal71 New Member

    Joined:
    May 25, 2010
    Messages:
    19
    Likes Received:
    0
    Trophy Points:
    0
    The volatile keyword may or may not help in a few specific situations, but it is no substitute for proper thread synchronization. What threading library are you using?
     
  4. singh_r85

    singh_r85 New Member

    Joined:
    May 25, 2010
    Messages:
    19
    Likes Received:
    0
    Trophy Points:
    0
    I am using "AfxBeginThread". Trying to startup (2) threads within my OnInitDialog function, as below;


    ==================================================

    BOOL CExampleDlg::OnInitDialog()
    {
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
    CString strAboutMenu;
    strAboutMenu.LoadString(IDS_ABOUTBOX);
    if (!strAboutMenu.IsEmpty())
    {
    pSysMenu->AppendMenu(MF_SEPARATOR);
    pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
    }

    // Set the icon for this dialog. The framework does this automatically
    // when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon

    // init the radio buttons
    CheckDlgButton (IDC_RADIO1, BST_CHECKED);

    //Start Threads
    AfxBeginThread( thread1, m_hWnd, THREAD_PRIORITY_NORMAL );
    AfxBeginThread( thread2, m_hWnd, THREAD_PRIORITY_NORMAL );

    return TRUE; // return TRUE unless you set the focus to a control
    }

    ================================================================== :eek:
     
  5. mmondal71

    mmondal71 New Member

    Joined:
    May 25, 2010
    Messages:
    19
    Likes Received:
    0
    Trophy Points:
    0
    Please show thread1 and thread2, and tell us if these are the only threads that access LampRadiance. If not, then describe how other threads access LampRadiance.

    Typically, problems in multithreading arise because there is no synchronization for access to shared data. Here, a critical section might be an appropriate vehicle for synchronization. Do you have any synchronization?
     
  6. spoddar66

    spoddar66 New Member

    Joined:
    May 25, 2010
    Messages:
    23
    Likes Received:
    0
    Trophy Points:
    0
    The OP said it appeared that Thread 1 isn't updating the value. According to his original description, he says thread 1 updates it and thread 2 uses it. Based on this, he needs synchronization.

    I don't believe updating a long is an atomic operation so the fact that it's only 1 value doesn't matter.

    On Windows, you can use the standard synchronization primatives (critical section, mutex, etc) or InterlockedExchange64 for longs.

    As far as using global variables. Globals are rarely ever a good idea in C++, and even less so when threading is added to the mix.

    Consider sharing a singleton class between the threads and expose thread safe accessor methods. That way, all the thread synchronization is encapsulated inside the class and the users of the class calling the accessor methods need not worry about the thread synchronization details.
     
  7. pkbis28

    pkbis28 New Member

    Joined:
    May 25, 2010
    Messages:
    24
    Likes Received:
    0
    Trophy Points:
    0
    There are no special cases. Standard volatile provides no useful guarantees related to multi-threaded programming. Whether it's global or not, when multiple threads access the same memory location, where at least one thread is writing - those accesses must be synchronized using the synchronization primitives provided by your threading library.
     

Share This Page