如何在Matlab调用的mex函数中使用Matlab引擎

时间:2012-03-07 12:52:44

标签: c multithreading matlab mex matlab-engine

我想创建一个可以从Matlab调用的mex程序,用户可以在其中注册用于处理的Matlab函数。然后,程序将使用此功能处理来自后台其他程序的数据。 mex程序和外部程序之间的通信是通过共享的全局缓冲区进行的,我用互斥锁来跟踪它。那部分实际上似乎有效。问题是Matlab是单线程的,我想在后台处理数据,以便用户可以继续使用Matlab。由于Matlab是单线程的,我的解决方案是创建一个新线程并从中启动Matlab引擎。为此,我需要从Matlab调用的mex文件中调用Matlab引擎。当我尝试这样做时程序构建正常,但是当我尝试打开一个新引擎时,Matlab崩溃了。使用下面的测试示例,如果我使用test('process2') Matlab停止调用程序(来自Matlab内部),并且当我使用ctrl-c Matlab崩溃时。使用test('process')有时似乎有效,但可能会在10次调用中崩溃Matlab。

#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);
  }
}

1 个答案:

答案 0 :(得分:0)

如果它仍然是一个问题,我编译你的代码没有线程部分(只有“process2”情况)没有错误,没有停止,没有问题。 即。

#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);
}
跑得很好。我在使用Visual Studio 2010的Windows机器上。

尽管如此,通过mex处理Matlab引擎显然有些特殊之处。在此链接上,您可以找到我最近的类似案例,以及解决方法: http://www.mathworks.com/matlabcentral/newsreader/view_thread/327157#898916