LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

how should I use semaphore?

 


@Vasilich2004 wrote:

 

I would prefer to create structure with serial port and semaphore instead of your second VI.


I'm not sure what you mean by that, but you should note that using the second piece of code to manage the semaphores is a lot safer (and as you can see, is a pretty simple piece of code). If you don't use it, you'll probably run into problems and bugs at some point.

 


___________________
Try to take over the world!
0 Kudos
Message 11 of 15
(1,913 Views)

I modified the program and I used cluster (structure) consists of SerialPort handle and SerialPort semaphore. At start program connects to serial port, creates semaphore, and creates a cluster. Then the cluster is used as input of each vi and each vi acquires semaphore, uses serial port, and releases semaphore.

So far so good ... but I was asked some special actions and met issue with semaphore again. Program can't acquire semaphore twice!

For example, in simple motion I use "Move"  VI which consists of "Start" and "Wait" VIs. At the same time, I use "Start" and "Wait" VIs themself in compex motion where I need to make other actions during motion. If program would acquire semaphores in "Move" and "Start"/"Wait" VIs (twice!) then program hangs when try to acquire semaphore second time. I suppse that is due LabVIEW's feature which is "Move" and "Start"/"Wait" VIs can work in different theads.

To avoid that I added bool "Acition" into the cluster. "Start" VI acquires semaphore, sets Action = Yes which will show any VI that device is moving, and release the semaphore. In "Wait" VI waits that the motion finished, acquires semaphore, and sets Action = No.

That should work but if the program will calls "Wait" in another line then I will have trouble.

 

I am wondering is another way in LabVIEW to implement this?

0 Kudos
Message 12 of 15
(1,852 Views)

Here are two basic options:

 

  1. Move the lock into the communication VI, as shown in my previous example, and use that VI to do ALL the communication. This will mean that different commands won't wait on each other, because only the comm part is shared.
  2. If you need to have several actions done one after the other, then you need another lock at a higher level. You're using a semaphore, but I suggest that you replace it with a data value reference, which shows more clearly where things are locked and unlocked. If you always use the DVR at the outer layer to get the VISA reference, then perform all the tasks and then release it, then any series of tasks will always be atomic.

If you want to make this more complicated, you can use a class, which will allow you to hold more information about your object and will allow you to create a set of public and private VIs, which means people who want to use your VIs can't make a mistake because they can't call the private VIs. The public VIs will get the DVR as the input and inside you will unlock the DVR and do whatever actions you want.


___________________
Try to take over the world!
Message 13 of 15
(1,841 Views)

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

2. If you need to have several actions done one after the other, then you need another lock at a higher level.

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

 

This is good suggestion but it doesn't work in my case. I need something like that

=======

Mutex MutexObject = new Mutex();

void Action( ActionType oActionType){

switch( oActionType){

case ActionType.FancyMotion:

StartMotion();

MakeSomething();

WaitMotionFinish();

break;

case ActionType.SimpleMotion:

Move();

break;

}

 

void Move(){

MutexObject .Lock();

StartMotion();

WaitMotionFinish();

MutexObject.Unlock();

}

void StartMotion(){

MutexObject.Lock();

//check Is finish in loop

MutexObject.Unlock();

}

 

void WaitMotionFinish(){

MutexObject.Lock();

//start motion

MutexObject.Unlock();

}

 

In usual language Mutex can be locked multiply times by same thread. Of course, it must be unlocked the same times as was locked. 

 

0 Kudos
Message 14 of 15
(1,825 Views)

If I understand that correctly, you're using a form of locking which allows code in the same thread which locked the mutex to also lock it again and access it. This seems to work based on the assumption that the code is linear and will behave predictably. LV doesn't have something similar because you don't have explicit control of threads and because the code is parallel, not linear.

 

However, as I said, if you create a public API which only uses the DVR and a private API which uses the object itself, you should be getting essentially the same thing, except you will need a wrapper method for every private API method which you want to include in the public API (StartMotion, in your example). I don't particularly like it either, but that's what there is. You can find all kinds of discussions on the topic online. Particularly in the OOP forum in the LAVA forums.


___________________
Try to take over the world!
0 Kudos
Message 15 of 15
(1,800 Views)