Functional global variable

I would like to ask to the experts a question about functional global variables. 
In the labview basics 2 course was said that a functional global variable is not reentrant. 
My purpose is to implement a code in such a way.2 main vi's. The first vi deals with some hardware that writes data in an output file with 1 Hz rate (more or less 1Hz, I cannot decide it).
The second vi deals with a different hardware (thermocouples). This works at a different rate (I cannot match exactly the different rates). I would like to write the data from the second hardware in the same output file of the first vi. 
I am thinking to use a functional global variable to pass the information from the second vi to the first vi. In this way I am using the data from the thermocouples at a rate given by the first vi. But at the same time in the global variable the data are written at a rate given by the second vi.
My question is: what exactly happens if the subvi (functional global variable) is called exactly at the same time? As you can understand it's not really important if I read the temperature with an error of 1 second, but I would not like the execution would stop or something like that. 
A functional global variable is a subVI that is not reentrant. This means that when
the subVI is called from multiple locations, the same copy of the subVI is used.
Therefore, only one call to the subVI can occur at a time.functional global variable is a subVI that is not reentrant. This means that whenthe subVI is called from multiple locations, the same copy of the subVI is used.Therefore, only one call to the subVI can occur at a time.

A couple of quick comments to add to this thread.
FG's can be involved in Race Conditions if two callers attempt to direct set the same value. An Action Engine (well what do you expect?) can be coded to help with those situations.
Example:
In arecent app I needed to set the heaters to "0" if an over-pressure condition was detected. The Heater set points where driven by a PID. The safety conditions where controlled by a process monitoring the input values.
So how do I keep the PID from setting the heater when the rig is not safe?
A Safety AE !
Actions used by the pressure monitoring set the Safety AE in an "go-safe" state where setting the heaters results in a null op.
This particular pattern (two writters) screams for an AE to coordinate the vaious actions. Do this same thing with queues could get tricky.
So for the Q in this thread we have a pattern of "two source of info, one sink for each" that screams for a queue.
BTW:
The AE Nugget linked above addresses what happens when two callers attempt to call the same non-re-entrant sub-VI.
Have fun,
Ben
Ben Rayner
I am currently active on.. MainStream Preppers
Rayner's Ridge is under construction

Similar Messages

  • Using functional global variables to transfer data between touch screen device and other targets

    Hi,
    We are currently developing a control system that will operate on a cRIO with a touch screen interface. During development we have been using functional global variables (FGVs) to handle most of the settings/data etc, however we have just realised that we may have an issue updating the data on the touch screen, and vice versa.
    Previously we have implemented similar programs using shared variables, however we were wondering if there is anyway to implement FGVs in a similar manner, whether it'd be a combination of FGVs and shared variables.
    Regards,
    Mike
    Software version: Labview 8.2.1

    See this thread on LAVA about sharing FGV's across projects. THis should be extendable to cross paltforms (I believe).
    You also may want to concider an upgrade to LV 8.5.1. We have found a number of performance related issues with LV 8.2.1 and RT.
    If you decide not to upgrade, just remeber what I wrote (above) when you have reason to question the performance.
    Ben
    Ben Rayner
    I am currently active on.. MainStream Preppers
    Rayner's Ridge is under construction

  • Functional Global Variable in the CLAD sample Exam

    Hello,
    A question in the CLAD sample exam #2 keeps puzzling me. It's question number 32 about FGVs:
    32. Which is not an important part of creating a Functional Global Variable?
    a. Using Shift Registers to store information
    b. Changing the VI’s execution settings to Reentrant
    c. Setting the VI to inline into calling VIs
    d. Setting the While Loop to stop after one iteration
    The answer given is the following
    32.Correct Answer: B
    Topic: Functional Global Variables
    Justification: It is not necessary to inline functional global variables into their calling VIs. In fact, inlining requires that the subVI be reentrant, which is forbidden for functional global variables.
    Clearly, for an FGV to work properly, the VI must NOT be reentrant. So I would have selected answer B, but the justification seems to clearly point to answer C as well, doesn't it? Is it a typo, a subtlety in the wording? I am stuck on this one!
    Solved!
    Go to Solution.

    Well, inlining requires reentrant.  Therefore, the best answer should technically be C.  This looks like one of those rejected/retired questions since it isn't quite right and/or left up to too much interpretation.
    There are only two ways to tell somebody thanks: Kudos and Marked Solutions
    Unofficial Forum Rules and Guidelines

  • Functional Global Variable on Hold

    Hello everyone,
    I understood, by reading threads on the forum, that a call to a Functional Global Variable will block its execution if the FGV is already being accessed by another VI, correct? Is there any other way it would block, apart from the stated?
    The motive of the question is that I have one FGV (non-reentrant) that is read by 8 subVIs concurrently (they are, actualy, the same vi, but configured to reentrant) and whose access time varies, strangely, based on the number of subvis running.
    When less than 5 VIs are trying to access the FGV, the execution is blocked (I assumed it, because when the FGV is disabled and replaced by a constant there is no problem with the execution) and the access lasts at least 50 ms; if this number is between 5 and 8, the execution is done much faster. My first guess was that the FGV hasn't been initialized until the fifth subVi is called, but I don't know how to check that.
    I can figure that there is something wrong with the FGV, but can't put my finger on it. Any ideas?
    Thank you in advance for any help.
    Solved!
    Go to Solution.

    Thank you for your response, Ben
    I'll try to explaing the problem better with the images that follow.
    I have 8 concurrent instances of the "bitDefiner.vi" - shown below - in the program.
    It reads from the AE (a simple read-write one) and it's the only one to call it besides the writer (that generates the appropriate signal), gets the rising edge of a waveform and determines how long it takes until the falling edge, giving a category to this time later on. If it doesn't determine the period between rising and falling edge before the timeout runs out, it aborts the execution of the while loop. This VI execution is setup like this:
    That being said, let's go to the problem.
    Assuming there is nothing using the AE but one instance of the bitDefiner, it won't get the rising edge, due to the fact the signal is not being generated, resulting in a timeout. The return value on the diff indicator should be next to the one defined to timeout(image below)
    However, when the subvi concludes its execution, the diff indicator shows 54ms intead of 15ms; so I concluded that the AE is taking to long to process the call. Besides that, I'm quite positive that there is only one thread accessing the AE.
    After this result, I ran the other instances of the bitDefiner and after the 5th one got activated, the diff went to the expected 15 ms (I'm still thinking how to show that on picture).
    I tried highlighting the execution, but it didn't show me anything unsual. The call chain just present that the caller is the bitdefiner VI as expected.
    Any thoughts on that?

  • Functional global variable question

    Hello,
    I fully understand how a functional global variable (FGV) works and its purpose but I have one last question.
    How do I guarantee (or how is it guaranteed) that my sub-VI (the FGV one) is not re-entrant, in other words, how am I sure that when an instance of the FGV is running it does not loose the processor to others?  Is this an option that I can choose in a sub-VI or is it related to the while loop or case strucure that compose a FGV?
    Joao

    Hi Joao,
    For a little more background on configuring reentrancy and the options you have available if you do want to make a subVI reentrant:
    LabVIEW Help: Reentrancy: Allowing Simultaneous Calls to the Same SubVI
    http://zone.ni.com/reference/en-XX/help/371361K-01/lvconcepts/reentrancy/
    As Lynn said, all new SubVIs will be non-reentrant by default.
    Regards,
    Tom L.

  • Function global variable(FGV) template

    Hi All 
    if NI adds the Fuctional Global Variable (FGV) tempalte in design pateren tempates in hte New window, it is easy to create FGV VI's.
    and Helps the programmers, no need to create from the begining of VI.
    Even it is usefull for CLD Exam also.

    Something like this? Note that I would use the term "Action Engine" instead of "Functional Global Variable" specifically to discourage the use of this template as a global variable and instead emphasize its role as an action performer on centralized data (as noted in the comments).

  • RT executable causes functional global variable VIs to become non-reentrant

    Hi,
    I am having a small issue with functional global variables (Repositories). The attached VI is a sample functional global variable I created that stores double precision numeric values. The VI properties are set to normal execution. I use this VI to pass data between loops running in real time on a PXI platform. When running my application from the project explorer (not creating executable) the VI functions as it should and passes data between my loops with no issues. But when I create a real time executable of my application and run it on the PXI, it does not share data between instances of the VI. My work around this issue is to change the VI properties execution priority to Subroutine but it forces me to modify my VI slightly for this to work (I have to remove the property node). I am not sure why this is happing. I have seen some applications with this VI that appear to function normally in development and in executable with the VI properties execution priority set to Normal. Any comments or suggestions are welcomed.
    I am running LabVIEW 2009, PXI-8186, and Windows XP
    Thanks
    Attachments:
    RT Repository DBL Numeric Command Ver 2.ctl ‏5 KB
    RT Repository DBL Numeric Element Ver 2.ctl ‏5 KB
    RT Repository DBL Numeric Ver 2.vi ‏25 KB

    Many properties require the front panel to be loaded in memory; the property you're using, NumItems, appears to be one of them (look at the help, you'll see that it says "Loads the front panel into memory.")  However, VIs running in an executable on RT do not have front panels, so those property nodes will not work.  If you were to log the error out terminal from the property node in your executable, you should see that an error occurs.  As a result, you're getting a 0 value out of the property node, causing your VI to output unexpected results.
    My recommendation is that you replace the property node with the function GetNumericInfo found in vi.lib\utility\VariantDataType.  It has an output called EnumNames.  Take the size of the EnumNames array and use that in place of the output from the property node.  This will work on RT.
    Note that this has nothing to do with re-entrancy, and the key hint is that the VI works when you remove the property node.

  • Storing DAQmx Task in a Functional Global variable

    Happy New Year to everyone!
    I got a nice little question hoping some of you might be able to help me....
    After initializing an starting a DAQmx task (V7.5), I wanted to store the task out reference in a functional global variable, but it seems, it didn't work.
    Everytime I tried to call a DAQmx VI with the opened reference, I get an error, the task would not be existing....
    I already made a workaround, so everything works fine. I'm just curious what I made wrong....
    Thanks in advance!
    Cheers
    Oli
    Programming languages don't create bad code, programmers create bad code....

    Helo Oli,
    Normally, you should not have a problem storing a task reference in a variable. However, the vi that created the task has to stay in memory for it to work. Closing the vi will result in the destruction of all created hadles -
    that is why your reference might be regarded invalid if you use it in
    another vi.
    That is why I can just assume that you are closing the VI that created the task before you are using the handle somewhere else. You can use variables to store the task ID, but as a workaround you have to keep the vi which reated the reference running.
    Hope this explains the behaviour.
    Regards
    Ingo Schumacher
    Systems Engineer Sound&VibrationNational Instruments Germany

  • Dynamic call of a vi with a reference stored in a global variable

    Hello,
    I am trying to program a VI which calls DAQmx functions in some cases, in other cases DAQmx may not even be installed. To prevent a broken arrow on machines where DAQmx is not installed, I want to use a sub-VI containing the DAQmx function calls which is called dynamically by a main VI. For speed I want to prevent continuous opening and closing the VI reference, so I want to store the reference to the sub VI in a global variable. In this variable I also want to store the Analog Input Task. I want to use an initialization VI to write the VI reference of the sub VI and to configure and start the Analog Input Task and write the Task ID to that Global, too. In that way I was hoping to be able to improve the performance of the dynamic calls and the Task calls. BUT - when I write the refererence and task to the Global and read it out from another VI, the reference is not valid anymore and the Analog Input task is also not valid, even if both the initialization VI and the Global are still open (but not running). Does somebody have an idea how to solve that? It is a bit difficult to describe, so here is what I want to do in a shorter description :
    - run a initialization VI which
      defines a reference to a sub VI which will be called dynamically later on
      and a AI task ID definining a DAQmx physical channel configuration to use for subsequent read cycles
      and writes both (VI reference and AI task) to a global variable
    - run another VI which
      reads the VI reference of the VI to call dynamically from that global
      runs the corresponding VI dynamically
      the dynamically called VI performs an AI task corresponding to the DAQmx task ID read from that global (it reads an analog value for instance from the  
      physical channel configured by that AI task) 
    Why all that? To prevent creating and destroying the VI reference for each call of the sub VI for speed. And to use the configured DAQmx channel for subsequent read tasks only if the subVI is called dynamically - if it is not, then the application will not see the DAQmx calls and therefore no broken arrow will occur if no DAQmx is installed on the machine.
    Can somebody help me with this? Why can't I store and read out the reference to the sub VI to/from a global, and why is the AI task not valid when read out from the dynamically called sub VI? I am somewhat lost with all that...
    Thanks in advance,
    Gabs

    Uh - I am almost getting crazy with that
    Kevin, that solution is the right one for programming an application. In that case everything will work fine. But during testing, it is more convenient to call all VIs from their front panels one after another. That's how I'm doing it for everything that needs to be exchanged between such VIs: store them either in a global or in a functional global variable. In that way the user can "play around" with the VIs without wiring them together in a main VI. Therefore, after some thinking I liked Davids idea with that daemon VI (I solved that by adding a boolean in the initialization VI to choose if that daemon is necessary - during testing phase - or not - when using the VIs in a main application). BUT:
    David: It does not work!!! I have exactly done what you proposed and this daemon VI is really running, having a True/False frame with a constant of False wired to the selector and holding both the functional global and the dynamically to call VI in the True frame. In that way, after initialization is finished, both VIs are still running but idle. Anyway, when I read back the value of the reference or the DAQmx task, it is invalid again!
    That really costs just too much time. Does anybody have any idea what to do now? David, I was hoping that your suggestion would solve the problem, because it would be logical that it would - why then is LabVIEW destroying the reference and task anyway even if that daemon VI containing the functional global is still running???
    Regards,
    Gabs

  • Software timing - Functional Global?

    I was reading NI Intermediate manual to prepare for the CLD exam, and noticed that they used Functional global variable in combination with timed loop for the software timing. Also, the error handling was implemented using functional global.
    However, I was reading in one post( not this forum) that the functional global is obsolete, can anyone shed any light on this issue, why would the functional global be obsolete: and if it is, what are acceptable design for software timing.
    Thank you.

    Cory K wrote:
    I dont see why a global would be obsolete.
    There are some instances when using a global variable is the best option, especially in cases when a resource will be used on several different computers.
    A functional global variable isn't the same thing as a global variable. A functional global variable is what was used before global variables were introduced in LabVIEW 3. It is the heart of an Action Engine.
    As for their obsolesence... Hah! That's all I have to say on that.
    As to the original post:  I'm a tad suspicious. What kind of software timing and error handling is being done with a functional global variable? Can you post the code?

  • Duplicate sub vi with the same global variable

    This is a simple question, that probably was answered before:
    I had a sub vi that uses a global variable. Now I need two of these sub vi's working simultaneously in a while loop. The problem is that they are both adressing the same global variable, but I need them to be isolated. How do I do that?
    Thank you.

    Hi Ivan,
    This Developer Zone article explains a little more background about why functional global variables are the best option for you. Happy coding!
    Amanda Howard
    Americas Services and Support Recruiting Manager
    National Instruments

  • Problems with global variable!!

    Hi!
    I am using some cluster (global variable), and certain fields in the cluster don't be updated.I can't understand where is the problem, because some fields are updated correctly and others no!!
    Any idea?
    Thanks in advanced!!
    Graci

    A functional global acts as a global variable in that it allows LV applications to access the data from different parts of the vi or from different vis for as long a LV is running. The vi is set to not be reentrant so that race conditions are avoided. Since functional globals are subvis that you write you also have the ability to store many global variables which are dependent upon only one input by performing the calculations within the functional global vi. You can certainly achieve this by using semaphores, but with functional globals this synchronization is built in.
    In the functional global vi you have a while loop which is set to stop after 1 iteration. This while loop has a shift register which holds the global data. There is a cas
    e structure to determine whether to read or write the functional global variable. In the write case the data from the input is written to the shift register on the right side. In the read case the data from the left shift register is written to the output and also passed on through to the right shift register. A good example can be found at the following link.
    http://sine.ni.com/apps/we/niepd_web_display.DISPLAY_EPD4?p_guid=B45EACE3DB4956A4E034080020E74861&p_node=174821&p_submitted=N&p_rank=&p_answer=&p_source=External

  • Is a functional global with loops inside case structure subject to race condition?

    Such as this one:
    Solved!
    Go to Solution.

    bmihura wrote:
    I'm being a bit dense here... would somebody write an example VI that demonstrates how functional global variables eliminate race conditions whereas a normal global variable would not? Or just describe it and I'll write the VI?
    The classic example used is a bank account.  Say you are making a deposit.  You have to read the current balance, add the deposit amount, and save the balance.  Now say you are making a withdrawal.  You have to read the current balance, subtract the withdrawal amount, and save the new balance.  Now let us say that both of these events happen at the same time.
    If you are using global variables, you read the global, perform the action, and save to the global.  But who reads what balance.  If both events read the balance at the same time, then whoever writes last will overwrite the other's action.  This is bad, especially if your deposit "didn't happen".
    Now using a FGV (or Action Engine), you can contain the critial parts of the code.  In this case the critical parts are the full read, act, and write.  So with the AE, you store the balance in a shift register.  You can perform whatever action you want inside of the AE VI.  Because the AE is not reentrant, only 1 action can be performed at a time.  So you make sure that deposit happens and is not overwritten by the withdrawal.
    Now for my caveat.  If all you do is a Get and Set inside of the FGV, it is basically a global variable, just slower.
    Read that acticle I linked to earlier and also read up on the Action Engine nugget.
    There are only two ways to tell somebody thanks: Kudos and Marked Solutions
    Unofficial Forum Rules and Guidelines

  • Function module Global variables not cleared from memory?

    Hi,
    This is may be simple & stupid question ( after posting  4242 posts ):)
    " Declaration in TOP
    data : begin of i_y1yatt occurs 0.
            include structure y1yatt.
    data : end of i_y1yatt.
    types: begin of t_yatt71.
           include structure yatt71.
    types: tcode like sy-tcode.
    types: dflag type c.
    types: end of t_yatt71.
    data : i_yatt71 type standard table of t_yatt71
                   with default key  with header line  initial size 0.
    This is code in the function module.
      loop at i_y1yatt.
        move-corresponding o_y1yatt to i_yatt71.
        if i_y1yatt-werks eq 'N501'.
           move space to i_yatt71-werks.
        endif.
        append i_yatt71. 
        " Here this internal contains the previous entry
        clear i_yatt71.
      endloop.
    This function module is called 25 times in a minute.
    My problem is this
    For example : 1st tranmission is called this fm with 50 records,
    and 2nd tranmission is called fm with 10 records.
    My results are showing
    last record in the 1st transmission is still on the memory while calling 2nd transmission.  ( Here in int table I_YATT71 still contains the 1st transmission's last records during the 2nd tranmission call)
    As per my knowledge if each time calls comes in to fm all gloabl variables get cleared. but some how this not happening.
    Anybody come across this scenario.
    PS. I know i need to use clear statement within the loop as first statement.

    You must understand that when calling a FM, you load the entire function group into memory. IF there are global variables, then they are "alive" for the entire duration of the program execution. Meaning if you call the function numerious times, or even if you call another function within the same function group, the functions still have access to that same global variable space, so it must always be cleared manually by the developer at the required points.  You can not rely on the runtime to clear the global variables at the end of the function call.  So you should clear all you globals as the first operation in your function module call, if that is what is required.
    Is this clear?
    Regards,
    Rich Heilman

  • How to modify global variable in a function?

    Hello,
    I want to modify a globalvariable in a function, at first I did it this way:
    class Global_output_class
    GlobalDim("Correlation_Status,fail_part,End_Exp")
    dim pouet
    Correlation_Status = 12
    Call Correlation()
    pouet = Correlation_Status
    Function Correlation()
    Dim Global_output_class_sub
    Set Global_output_class_sub = new Global_output_class
    Correlation_Status = 1
    fail_part = 2
    End_Exp = 3
    Global_output_class_sub.CorrelationStatus = Correlation_Status
    Global_output_class_sub.failpart = fail_part
    Global_output_class_sub.EndExp = End_Exp
    set Correlation = Global_output_class_sub
    End function
    In this case: correlation_status receive the value 12, then I go to my function correlationn() where it became 1
    Then it goes out of the subfunction and takes the previous value from the program(12) ( I dont want that)
    To solve the problem I made it this way:
    class Global_output_class
    public CorrelationStatus
    public failpart
    public EndExp
    end class
    GlobalDim("Correlation_Status,fail_part,End_Exp")
    Correlation_Status = 12
    Set Global_Output = Correlation()
    Correlation_Status = Global_Output.CorrelationStatus
    fail_part = Global_Output.failpart
    End_Exp = Global_Output.EndExp
    pouet = Correlation_Status
    Function Correlation()
    Dim Global_output_class_sub
    Set Global_output_class_sub = new Global_output_class
    Correlation_Status = 1
    fail_part = 2
    End_Exp = 3
    Global_output_class_sub.CorrelationStatus = Correlation_Status
    Global_output_class_sub.failpart = fail_part
    Global_output_class_sub.EndExp = End_Exp
    set Correlation = Global_output_class_sub
    End function
    This way my global value are recopied in themselves after leaving the subprogram
    I got a lot of variables, is there any easier way so the global variable modified in a function keep the value after leaving the function?
    Thanks for help,
    Fred
    Solved!
    Go to Solution.

    Hi Fred,
    it is possible to use a global defined variable but the better way is to use to use a funtion call (or procedure call) with parameters. Please find first the good solution for a funcion call with parameter and the sub-optimal way with an global valiable:
    dim oParameter
    set oParameter = new cGlobal_output_class
    oParameter.Correlation_Status = 12
    msgbox "Correlation_Status before Call Correlation: " & oParameter.Correlation_Status
    Call Correlation(oParameter)
    msgbox "Correlation_Status after Call Correlation: " & oParameter.Correlation_Status
    Function Correlation(oPara)
    msgbox "Correlation_Status in the FUNCTION before change: " & oPara.Correlation_Status
    oPara.Correlation_Status = 1
    oPara.fail_part = 2
    oPara.End_Exp = 3
    msgbox "Correlation_Status in the FUNCTION after change: " & oPara.Correlation_Status
    End function
    class cGlobal_output_class
    dim Correlation_Status,fail_part,End_Exp
    end class
    call GlobalDim("oPouet")
    dim oPouet
    set oPouet = new cGlobal_output_class
    oPouet.Correlation_Status = 12
    msgbox "Correlation_Status before Call Correlation: " & oPouet.Correlation_Status
    Call Correlation()
    msgbox "Correlation_Status before Call Correlation: " & oPouet.Correlation_Status
    Function Correlation()
    msgbox "Correlation_Status in the FUNCTION before change: " & oPouet.Correlation_Status
    oPouet.Correlation_Status = 1
    oPouet.fail_part = 2
    oPouet.End_Exp = 3
    msgbox "Correlation_Status in the FUNCTION after change: " & oPouet.Correlation_Status
    End function
    class cGlobal_output_class
    dim Correlation_Status,fail_part,End_Exp
    end class
    Greetings
    Walter

Maybe you are looking for

  • It just wont work

    Basically i am using my macbook 1.83GHz and several problems have occoured, firstly programs keep quitting this mainly happens with microsoft word which often wont even open, it simply says error and then often after it has started it will very quick

  • HT4527 transfer i-tunes from my PC to an external drive

    My PC is using about 20g for just i-tunes and I need to i-tunes to an external drive but still usable on this computer how do I do this? By the way I really need this to be dummy proof since the one time that I did try this it just duplicted it and e

  • Song file paths changed to images

    i have my music folder set to an external harddrive and for some reason SOME of the songs to another harddrive and is pointing to random image files....is there any way to fix this and get it to find the correct files without re adding themm and tryi

  • DB Adapter infinite polling for the db

    Hi all Oracles I am facing a mazing pb. A BS publish all what is in the DB but, sometime with a duplication,X3,X4,, and so one) Any idea

  • Authorization hierarchy variables in QD

    Hi! Is it possible in Query Designer to create a hierarchy  authorization variable (i.e. based on a profit center), which is <b>editable</b>, searchable (F4) and the default value is automatically included from the authorization profile? -OV-