Matlab Compiler SDK plot waitforFigures execute multiple threads

I created a simple graph using matlab and created a java jar with matlab sdk compiler.

I can run a java function created by Matlab and see my plot.

I wanted to create multiple graphs and run the function on separate threads. It works. But if I run my java function to create multiple plots, the waitforFigure () method of the first thread waits for the rest of the plots to be closed too. So my first thread does not continue and locks up until the other sections created after they are also closed are closed.

I thought that the instance of a Java class object created by the Matlab compiler creates a new Matlab compiler runtime?!. Why is the waitforFigure method waiting for other graphs if it runs on a separate thread?

Here is my runFunction of the generated RunAlgorithm class. The runFunction methods create an instance of the Matlab Compiler SDK created by Class, Class1. Its the default name for the class. ThePlot function is matlab code, run at Matlab runtime and displays my data.

void runFunction( MWNumericArray x1, MWNumericArray y1, MWNumericArray z1) throws MWException {


Class1 thePlot = new Class1;

    /* Number of points to plot */
    try {


        /* Plot data */
    thePlot.runAlgorithm( x1, y1, z1);
    thePlot.waitForFigures();

    }

    catch (Exception e) {
        System.out.println("Exception: " + e.toString());
    }

    finally {
        /* Free native resources */
        MWArray.disposeArray(x1);
        MWArray.disposeArray(y1);
        MWArray.disposeArray(z1);
        if (thePlot != null)
            thePlot.dispose();
    }
}

      

Here is my simple flow of how it executes a function containing my Matlab class. I create an instance of the RunAlgorithm class, read data from a file, and pass it to MWNumericArray to the runFunction method. There is a waitforFigures method lock in my runFunction method.

Thread t1=new Thread() {
           public void run() {


        RunAlgorithm a = new RunAlgorithm();
        RunAlgorithm.Measurements n = null;

        try {
            n= a.readFile(selectecValue);
            System.out.println("File REad");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {

            a.runFunction(n.mX, n.mY, n.mZ);
        } catch (MWException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         }
            };
            t1.start();

      

Basically, I am reading a csv file, parsing my data into MWnumericArray and passing it to the RunAlgorithm class. This class internally creates a Class1 object with runFunction and displays my Matlab-Plot with the Matlab runtime.

EDIT:

If I run my application twice. The waitforFigure method simply waits for threads generated by a single application. Does this mean that the matlab runtime runs once with the application, regardless of the threads you created?

So the instance of Class1 doesn't start a new matlab runtime every time?

EDIT: If I compile my Matlab code as a Singleton then my plot is updated. Would this mean that initializing my Class1 object starts a new temporary matlab environment?

+3


source to share


1 answer


I looked at your problem and tried to create a Matlab jar on my machine. However, for some reason the creation of the jar file failed, so I created a dll for the .net application instead. The underlying principle should be the same.

Here is the binding of the constructors found in the generated C # code:

private static MWMCR mcr= null;
static Plotter()
{
  if (MWMCR.MCRAppInitialized)
  {
    try
    {
      /* a lot of codes here but deleted to make what is important stands out */
      mcr= new MWMCR("",
                     ctfFilePath, embeddedCtfStream, true);
    }
    catch(Exception ex) { //some code here }
  }
}

public Plotter()
{
  if(ex_ != null)
  {
    throw ex_;
  }
} 

      

And a method drawplot()

that tells Matlab current time to run a batch M-script.

public void drawplot()
{
  mcr.EvaluateFunction(0, "drawplot", new MWArray[]{});
}

      

As you can see, the MWMCR class is the actual Matlab instance that runs the M-script and is a static object. Therefore, no matter how many instances are Plotter

or are Class1

created, there is only one instance of Matlab. Several requests mcr.EvaluateFunction

are queued and executed one after the other. So, in theory, running multiple Matlab scripts at the same time is not possible without creating two MWMCR objects, which means you will need multiple instances of your java assembly ( experimentally verified ).




In your case, all drawings are rendered by the same instance of MWMCR, while WaitForFiguresToDie

or waitForFigures()

checks any open shapes drawn by MWMCR.

public void WaitForFiguresToDie()
{
    mcr.WaitForFiguresToDie();
}

      

The solution I can suggest for you is to include blank Matlab ( EmptyCode()

) code in your jar package . Then add something similar to the following in your Java code:

void runFunction()
{
    Class1 thePlot = new Class1;
    Thread t1=new Thread() {
       public void run() {
           Class1 thePlot = new Class1;
           thePlot.waitForFigures();
           }
    }
    Thread t2=new Thread() {
       public void run() {
           Class1 thePlot = new Class1;
           thePlot.waitForFigures();
           }
    }
    thePlot.waitForFigures();
    t1.start();
    t2.start();

    //your java code

    thePlot.EmptyCode();
    thePlot.waitForFigures();
}

      

+2


source







All Articles