There are many ways you can accomplish this task, but passing the VI reference to the subVI is probably the easiest. Some examples of other ways, with editorial comments (reader warning, professor mode engaged

)
- Create a user event and pass it to the subVI. If you have an event structure in your main VI (if you have a UI, you should), this is pretty easy, since it will use functionality (close or abort) that is already there.
- Create a queue and use a producer-consumer architecture to handle the event. The producer is in the subVI, the consumer in the main VI. The queue reference can be passed to the subVI or created there, if it is a named queue. If your main VI uses a queue-driven state machine architecture, this ends up being almost identical to method 1.
- Create a thread-safe reference object containing a boolean and use a polling loop in the main VI to determine when the boolean goes TRUE, signalling a quit. With the plethora of other, non-polling, methods available, this should only be used when the architecture is very simple. Fortunately, it is relatively simple to convert to methods 1 or 2, if need arises. Commonly used thread-safe reference objects are constructructed from uninitialized shift registers or single-element queues (my current favorite). For more information, search this forum using such keywords as "action engine", "labview 2 global", "shift register global", or "single element queue".
- Use a non-thread-safe reference object (e.g. global, shared variable, datasocket variable) as in 3. This is only appropriate if you can guarantee there will only be one writer. LabVIEW is an inherently multi-threaded environment, so race conditions become a major issue very quickly if you have multiple readers/writers and unlocked data.
Take-home message: if your main VI does not have any cleanup tasks, use a passed VI reference to close it. If it does, methods 1 or 2 above are more appropriate. If you have any questions about any of the above, please ask.