1

I want to make a mex program that can be called from Matlab, where the user can register a Matlab function to be used for processing. The program will then use this function to process data coming from another program in the background. The communication between the mex program and the external program is trough a shared global buffer, which I keep track of with mutex locks. That part actually seems to work. The problem is that Matlab is single-threaded and I want to process data in the background, so that the user can keep working with Matlab. Since Matlab is single-threaded my solution is to create a new thread and start Matlab engine from it. For this I need to call Matlab engine from a mex file called from Matlab. When I try to do this the program builds ok, but when I try to open a new engine Matlab crashes. Using the test example below, if I call the program (from inside Matlab) with test('process2') Matlab stalls, and when I use ctrl-c Matlab crashes. Using test('process') sometimes seems to work but crashes Matlab in maybe one of ten calls.

#include "mex.h"
#include <stdio.h>
#include <string.h>

#include <pthread.h>
#include <errno.h>
#include <stdlib.h>

#include <matrix.h>
#include <unistd.h>
#include "engine.h"


void* local_process(void *arg) {

  Engine *engine;
  engine = engOpen(NULL);
  engClose(engine);
}    

void mexFunction( int nlhs, mxArray *plhs[],
          int nrhs, const mxArray *prhs[]) {

  if ( (nrhs<1) || (! mxIsChar(prhs[0])) ) {
    mexErrMsgTxt("First argument should be a command (string)");
    return;
  }

  /* Read command string */
  int buflen = mxGetNumberOfElements(prhs[0])+1;
  char* buf = mxCalloc(buflen, sizeof(char));
  if (mxGetString(prhs[0], buf, buflen) != 0)
    mexErrMsgTxt("Could not read command string");
  mexPrintf("Command: %s\n",buf);

  if (strcmp(buf,"process")==0) {
    pthread_t thread;
    pthread_create(&thread,NULL,local_process,NULL);
  }
  else if (strcmp(buf,"process2")==0) {
    Engine *engine;
    engine = engOpen(NULL);
    engClose(engine);
  }
}
snowape
  • 1,274
  • 10
  • 23
  • I think [this link](http://www.mathworks.com/matlabcentral/newsreader/view_thread/45742) or some of these [Thread safety of Matlab engine API](http://stackoverflow.com/questions/248421/thread-safety-of-matlab-engine-api). It sounds like processes and not threads are the way to go. – macduff Mar 07 '12 at 15:14
  • The issue in both those links is a problem with multithreading i.e. accessing a Matlab engine or Matlab function from several threads. In my example above each engine is only accessed by one thread, but it still doesn't work. – snowape Mar 07 '12 at 16:38
  • Just an idea. Have you tried calling any of the built-in Matlab tools for multithreading? For instance, the `batch` command, or starting a `timer`, where you can run a callback function periodically. – mattgately Mar 08 '12 at 14:29
  • I want Matlab to process data when it's available from the outside so I cant use timer. Using the Parallel Computing Toolbox (which batch is part of), is worth a try, but if possible I would like to avoid being dependent on it. – snowape Mar 08 '12 at 23:03

1 Answers1

0

If it still is of a concern, I compiled your code without the thread part (only "process2" case) with no error, no stalling, no problem. i.e.

#include <mex.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <matrix.h>
#include <engine.h>

void mexFunction( int nlhs, mxArray *plhs[],
    int nrhs, const mxArray *prhs[])
{
    if ( (nrhs<1) || (! mxIsChar(prhs[0])) )
    {
        mexErrMsgTxt("First argument should be a command (string)");
        return;
    }

    /* Read command string */
    int buflen = mxGetNumberOfElements(prhs[0])+1;
    char* buf = (char*)mxCalloc(buflen, sizeof(char));
    if (mxGetString(prhs[0], buf, buflen) != 0)
        mexErrMsgTxt("Could not read command string");
    mexPrintf("Command: %s\n",buf);

    Engine *engine;
    engine = engOpen(NULL);
    engClose(engine);
}

ran well. I am on a windows machine, with Visual Studio 2010.

Nevertheless, there are apparently peculiarities dealing with Matlab engine through mex. On this link you can find a recent similar case that I had, and a workaround: http://www.mathworks.com/matlabcentral/newsreader/view_thread/327157#898916

hamid attar
  • 388
  • 1
  • 8