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")?
declare LampRadiance as volatile. This makes sure that the processor isn't caching the variable. example : Code: long volatile LampRadiance;
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?
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 } ==================================================================
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?
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.
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.