LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to suspend a thread to ensure other ready threads run before proceding?

(CVI 5.5.1 on NT)
I have a case where I tried to use double locks to synchronize two threads (lock-step) during their initialization, but couldn't. For example, if I GetLock() from thread A, I can't use ReleaseLock() from thread B on the same lock. I can go to the WinSDK to get this capability, but I haven't needed the SDK for anything else, and I'm leary of mixing CVI locks & threads with those in the SDK.

Can I use ProcessSystemEvents(), or Sleep(0), with confidence to allow other ready threads to execute? This would be used between a ReleaseLock() and a GetLock() to ensure that another thread has been able to satisfy its own GetLock()?

This is a lame form of synchroniza
tion, but Locks don't seem to be real Mutex or Semaphore objects that can be managed across threads.

I am trying this because I can't use ConnectToTCPServer, and allow retries, from a thread that is not planning to 'own' the connection (previously posted question).

I may need to split up the process and use PostDeferredToThreadAndWait() instead.
0 Kudos
Message 1 of 4
(3,426 Views)
Jon,

Short answer:
You can use ProcessSystemEvents or Sleep(0) or Delay(0) as you describe. I believe you also would need to use a global to indicate your state. Check out the implementation of InitializeMultithreadingIfNecessary in toolslib.c. I don't think this is exactly what you're trying to do, but it should be of some help.

You also could use PostDeferredCallToThreadAndWait as you suggest. This might be the simplest solution.

More info:
CVI locks are wrappers around Mutexes or Critical Sections (depending on whether you name the lock or not). Even with OS locks, you can release them only from the thread that acquired them so CVI is not introducing a limitation here.

I think that I would use OS event objects to do what I think you are trying to do. You creat
e two event objects (call them 1 and 2). You have thread A wait for event 1. When thread B is done its initialization, you have it signal event 1 and wait on event 2. When thread A is done its intialization, you have it signal event 2. Then both threads go on their merry way.
Message 2 of 4
(3,426 Views)
Thanks drohacek,

I've used mutex-type objects in Unix & real-time OSs before without this limitation. After reading more NT info, it appears that when I created an unnamed lock, it may have implemented a critical section. This explains the cross-thread restrictions.

After writing the question, I realized that CVI doesn't include the sleep() function (or many other POSIX-isms). Delay(0) doesn't appear to force the switch (could've been my problem though). PostDeferred..Wait and a single lock seems to cover my need.

Thanks again for your response.
0 Kudos
Message 3 of 4
(3,426 Views)
More info...

The windows Sleep(0) function doesn't appear to be causing a thread switch (relinquishing its time slice) during my recent testing. This causes Delay(0) AND Post&Wait (which uses Sleep(0)) to not work as expected! I rebuilt the toolbox & stepped through it to check. However, a simple Post..Thread and a controlled ProcessSystemEvents loop seems to work.

Have I done, or missed, something obvious?
0 Kudos
Message 4 of 4
(3,426 Views)