Re: Service multiple mathlinks
- To: mathgroup at smc.vnet.net
- Subject: [mg25203] Re: Service multiple mathlinks
- From: tgayley at wolfram.com (Todd Gayley)
- Date: Fri, 15 Sep 2000 02:21:41 -0400 (EDT)
- Organization: Wolfram Research, Inc.
- References: <8onfgc$oq5@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
On 1 Sep 2000 01:40:28 -0400, "Eric and Rachael Farmer" <erfarmer at erols.com> wrote: >This is my first post here; I have scanned this group for a while looking >for references to my problem, but haven't found any. Any help is >appreciated... > >I am working on an OpenGL application that uses a MathLink interface with >Mathematica. I have developed "versions" of this application that use two >distinct approaches: > >1. The OpenGL window is created from Mathematica, but then operates (for >the most part) independently of Mathematica; contents of the window can be >periodically modified or read from a Mathematica session via MathLink >template functions. This allows GUI window "stuff" and separate Mathematica >front end stuff to go on simultaneously, but at a price: the GUI window >process can't initiate a Mathematica computation and retrieve a result, >since the kernel is a slave to the front end connection. > >2. A Mathematica function initiates "operation" of the OpenGL window, which >then works as before, but in addition can get computation results from the >kernel. This time, the price is loss of access to the kernel by the front >end until the GUI window gives it up. > >What I'm really looking for, then, is the ability to make the kernel >"service" multiple mathlinks. This would allow front end use of the kernel, >but at the same time allow the GUI window process to get "immediate" >responses from the kernel as well. I imagine this somehow involves >manipulation of $ParentLink, but I have been unable to make it work. Is >this possible, and if so, how is it done? Eric, This is a very advanced question, and you are in luck, because this exact problem needed to be solved for J/Link. J/Link allows users to write Mathematica code that creates and controls Java windows and other user interface elements. I realized early on that it was highly desirable to allow these windows to turn around and drive the Mathematica kernel themselves without tying up the kernel's attention and thus interfering with the user's interactive session in the notebook front end. These are described in the J/Link User Guide as "modeless" interfaces, meaning modeless with respect to the kernel--they do not require its exclusive attention while they are active. The best part is that this functionality is written in top-level Mathematica code, and it really has nothing to do with J/Link specifically. Any program like yours that needs to enable the state of having one kernel service multiple front end-type programs can use the feature. The function that does this is called ShareKernel, and here is an exmaple of how you might use it for your application. In[1]:= <<JLink` (* Here we start up the app as in scenario 1 that you describe. *) In[2]:= openGLlink = LinkLaunch["OpenGLApplication"]; In[3]:= LinkConnect[openGLlink]; (* ... Whatever initialization you need to do to goes here ... *) In[3]:= ShareKernel[openGLlink] That's it. ShareKernel returns right away, and the user's front end session continues normally. The OpenGLApp program can now call Mathematica as if it had launched the kernel itself. Both the front end and OpenGLApp operate as if they had exclusive access to the kernel. Provided your application allows it, you can continue to call it from Mathematica. In other words, you can have it both ways: the application can be "scripted" by calls executed from the front end (as in your scenario 1), and it can also be operated as a standalone interface that calls the kernel for computations (as in your scenario 2). There is one caveat--ShareKernel is not truly independent of the rest of J/Link. ShareKernel puts the kernel into a state where it is continually busy, and thus it will suck up a lot of CPU time. This is because yielding cannot be done effectively in top-level Mathematica code. ShareKernel relies on a call into the Java runtime for yielding, and this reduces the CPU load to negligible levels. ShareKernel works fine without Java running, but it will keep your CPU load at 100%. To fix this, all you need to do is call InstallJava: In[4]:= InstallJava[] Some readers may be wondering why manual manipulation of $ParentLink is not a solution to this problem. Although you can achieve sharing of one kernel with multiple front ends by alternately pointing $ParentLink at each link, this is much too obtrusive to the user. Applications like J/Link and the OpenGL program under discussion here require seamless sharing of the kernel. Finally, I should note that there are other solutions to this problem. I know of two programs that allow one kernel to "multiplex" more than one front end-type program. One is called Serializer, written by Chikara Miyaji (and which I believe will be included with the upcoming book "MathLink: Network Programming with Mathematica" by Miyaji and Abbott [I hope I got that right]), and the other one is called MultiLink, which comes with Mathematica Link for Excel. These programs are similar in that they sit between the kernel and the front end(s), listening to multiple links and allowing them sequential access to the kernel. The drawback to this solution is that you have to know ahead of time, when you first launch the kernel, that you will need this multiplexing facility. This is because you connect your front end program not to the kernel, but to Serializer or MultiLink. With ShareKernel, you can turn on (and off) sharing in the middle of a session, so your users don't need to do anything special. --Todd Todd Gayley Wolfram Research