LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Thread locks in LabWindows

At the site: http://zone.ni.com/devzone/cda/tut/p/id/3663 regarding multi-threaded application development there is the following code snippet:

-----

int lock;
int count;

int main (int argc, char *argv[])
{
    int functionId;
    CmtNewLock (NULL, 0, &lock);
    CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, ThreadFunction, NULL, &functionId);
    CmtGetLock (lock);
    count++;
    CmtReleaseLock (lock);
    CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionId, 0);
    CmtDiscardLock (lock);
}
int CVICALLBACK ThreadFunction (void *functionData)
{
    CmtGetLock(lock);
    count++;
    CmtReleaseLock(lock);
    return 0;
}

----


But I'm having a hard time understanding how count is at all related to lock. What if I have multiple global variables that need to be locked in different threads, how is this handled?
0 Kudos
Message 1 of 6
(5,638 Views)

Hello coanda,

Thanks for posting on the NI forums.  Let me start by saying that you’re quite right.  CmtGetLock() does not put a lock on any variable, but instead it reserves ownership of the thread lock, which is named lock in this case.  An attempt to take ownership of the thread lock from a separate thread must wait until the owning thread releases the lock using CmtReleaseLock().  In other words, if thread 1 reaches the CmtGetLock() function before thread 2 does, then thread 2 suspends execution until thread 1 reaches CmtReleaseLock().  Once the lock is release by the first thread, the second thread can then reserve ownership of the lock, and continue execution.

So, if you desire to protect multiple global variables in different threads, you must only modify these variables when ownership of a lock is activated.  It is up to the developer to coordinate which lock is reserved when accessing a certain variable.  The important thing to understand is that there is never any lock put on a variable, rather ownership of locks themselves are reserved and released.  If we wanted to protect another global variable in the example from the above post named count2, then the modified code would look like the following:

-----

int lock;
int count;
int count2;

int main (int argc, char *argv[])
{
    int functionId;
    CmtNewLock (NULL, 0, &lock);
    CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, ThreadFunction, NULL, &functionId);
    CmtGetLock (lock);
    count++;
    count2++
    CmtReleaseLock (lock);
    CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionId, 0);
    CmtDiscardLock (lock);
}
int CVICALLBACK ThreadFunction (void *functionData)
{
    CmtGetLock(lock);
    count++;
    count2++;
    CmtReleaseLock(lock);
    return 0;
}

-----

 

Chris_G
Sr Test Engineer
Medtronic, Inc.
0 Kudos
Message 2 of 6
(5,610 Views)
Hi Chris_G, thanks for your clear explanation. That answers my question.
0 Kudos
Message 3 of 6
(5,605 Views)
How is CmtGetLock()/CmtReleaseLock() different form windows SDK EnterCriticalSection()/LeaveCriticalSection()? 

Are they wrapper functions around them to provide a way for the Linux runtime to do the Linux equivalent? 
If not, why should I use the Cmt functions instead of the SDK functions I'm used to?

As an aside, my externally visible Email has been changed, how do I update my forum profile?  I could see what it was set to with the forum MyProfile, but couldn't find a place to update it.

--wally.

0 Kudos
Message 4 of 6
(5,573 Views)

Hello wally_666,

 

Thank you for your questions as well.  Functionally speaking, CmtGetLock() and CmtReleaseLock() are no different than the Windows SDK EnterCriticalSection() and LeaveCriticalSection() functions.  When calling Windows SDK functions from LabWindows/CVI, one must include the proper header files and libraries in order to access the Windows SDK functions. Using the CmtGetLock() and CmtReleaseLock() functions from LabWindows/CVI eliminates this step, and also reduces compile time.  For more information on calling Windows SDK functions from LabWindows/CVI, see the following link:  Using the Windows SDK in LabWindows/CVI

 

As far as using the functions during runtime on a Linux machine, the LabWindows/CVI Run-Time Module for Linux supports these two functions, and therefore can be executed on a Linux machine.

 

Lastly, to update the current email address in your NI User Profile, follow these steps:

 

(1)    Log in to your profile

(2)    At the top of a discussion forum thread, click on the My Profile link, located just under the thread category (e.g. “LabWindows/CVI”)

(3)    On the Personal Profile tab of your NI User Profile, click on the Modify your NI User Profile link at the top of the tab.

(4)    Once the My Profile page pops up, click on the Modify Profile link, which is the third link down on the page.

(5)    On the Modify Profile page, you can change your email address in the textbox under the Enter your email address: heading.

 

Chris_G
Sr Test Engineer
Medtronic, Inc.
0 Kudos
Message 5 of 6
(5,537 Views)
Chris_G,

Thanks for the instructions on editing my profile, somehow I couldn't get to that page when I tried last week.

Saving compile time is no big deal for me and I've been mixing CVI and SDK code since the beginning (CVI 3) but I'll be using the Cmt routines in my next project as it'll save me learning about mixing Windows and Linux thread locking semantics, neatly solving the problem I'll face.

--wally.

0 Kudos
Message 6 of 6
(5,483 Views)