LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

change global variable multithreaded

Hi,

I've encounterd an issue which I'm trying to end a thread from another thread

I have one main thread that calls two different threads (Thread1 & Thread2) as so:

 

 

Thread1()
{
    ...
   while (g_ThLoop)
   {
          ...Do stuff...
   }
   ...Cleanning memory etc....
}
Thread2()
{
   g_ThLoop  = 0;
}

MainThread()
{
    ....
    g_ThLoop = 1;
   CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, Thread1, 0, &hFid1);
   ....Do Stuff...
   CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, Thread2, 0, &hFid2);
   CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, hFid1, 0);
   CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, hFid2, 0);
   CmtReleaseThreadPoolFunctionID (DEFAULT_THREAD_POOL_HANDLE, hFid1);
   CmtReleaseThreadPoolFunctionID (DEFAULT_THREAD_POOL_HANDLE, hFid2);
}

I've tried to debug in debug and release configuration but the change of g_ThLoop from Thread2 doesn't make Thread1 to exit

also tried to use CmtLock, Local Variable and Safe Variable but...with no success 😞

 

Uriya

 

0 Kudos
Message 1 of 7
(5,482 Views)

How is your g_ThLoop variable defined?

 

In Monitoring and Controlling Secondary Threads help topic the following note can be found:

Note  If you use the volatile keyword, this code will function properly in an optimizing compiler such as Microsoft Visual C++. An optimizing compiler determines that nothing inside the while loop can change the value of the quit variable. Therefore, as an optimization, the compiler might use only the initial value of the quit variable in the whileloop condition. Use the volatile keyword to notify the compiler that another thread might change the value of the quit variable. As a result, the compiler uses the updated value of the quit variable each time the loop executes.

 

Multitthreading is indeed a powerful technique but requires a non trivial knowledge of its inner aspects. I suggest you to carefully read Creating Multithreaded Applications topic in the CVI help: it gives the basics of multithreading and a lot of advanced features you should know to master this technique.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 7
(5,478 Views)

Thanks ,

 

you're right, I've forgot to write down the g_ThLoop declaration.

g_ThLoop is declared on top, using volatile like this: 

volatile int g_ThLoop;

 

I also tried to not use volatile and just using only int instaed, but with no success...

 

I have new info:

When I try to debug my program, I always come across that Thread1 is frozen which means that it doesnt do any IO and in the Threads monitor, it look grayed out (dimmed) so I think it got on a suspended mode or something like that.

Im not ruling out the possibility that the g_ThLoop doesnt change at all but it seems to me that it's not involved.

 

Uriya

0 Kudos
Message 3 of 7
(5,419 Views)

It may seems a silly comment, but have you tried to step into the thread function to understand whether it exits prematurely from the loop due to unpredictable conditions?



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 7
(5,416 Views)

From what I've learned in the life of the simple programmer - there is no silly comments 🙂

 

Actually I've checked if the thread exiting prematurely by putting a break point after its loop clause but nothing happend 😕  and whene I open Threads window (on CVI IDE) I can see it still 'alive'.

That why I think the thread went frozen..but maybe there is a better way to check if the thread is exiting or not...but that what i know about thread debugging...

 

so....no luck so far.....

 

0 Kudos
Message 5 of 7
(5,373 Views)

Can you reduce your project to a minimum that exposes only the behaviour we are discussing about?

Examining some real code may lead to some new idea to solve the problem.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 6 of 7
(5,370 Views)

Hi,

The (g_ThLoop) check cannot be done until "Do stuff" is done. So if it takes too much time or if it is stuck inside, the thread1 function is not  terminated.

Checking this by debuger may be useful. Do you know that you can switch the the debuger view in "Threads window"?, just double click on thread.

But do not be confused that the thread is not automaticaly closed when your Thread function is done. The thread remains in thread pool until application exit(so threads can be reused if need).

Also using some flag variables to check the state of thread1 may be useful (for example, does the thread1 start?, Does the thread1 reach the start of while cykle?,Number of iteration throught while cykle,...)

 

From other perspective, If you have multicore/multiprocesor system, the "volatile" keyword  is maybe not enought. Specialy if you enable agresive optimization the problem can be worse.

In your case, it is not very likely the problem (because this is very simple logic, and windows swap threads between processors,..) but for more safety  please use standard synchronization primitives from existing library library.

In this case:

while (__sync_fetch_and_add(&g_Thread,0)==0) //while (g_Thread==0)

__sync_fetch_and_add(&g_thread,1)            //g_thread=1;

 

You can also use  InterlockedCompareExchange and InterlockedIncrement functions.

 

I hope this help.

P.S. i am sorry for my bad english

0 Kudos
Message 7 of 7
(5,357 Views)