2012-03-07 213 views
1

我想制作一个可以从Matlab调用的mex程序,用户可以在其中注册一个Matlab函数用于处理。程序将使用此功能在后台处理来自另一程序的数据。 mex程序和外部程序之间的通信是通过一个共享的全局缓冲区,我通过互斥锁锁定了这个缓冲区。这部分似乎工作。问题是Matlab是单线程的,我想在后台处理数据,以便用户可以继续使用Matlab。由于Matlab是单线程的,我的解决方案是创建一个新线程并从中启动Matlab引擎。为此,我需要从Matlab调用的mex文件中调用Matlab引擎。当我尝试这样做时,程序可以正常工作,但是当我尝试打开一个新的引擎时,Matlab会崩溃。使用下面的测试示例,如果我使用test('process2') Matlab失速并且当我使用ctrl-c Matlab崩溃时调用程序(从Matlab内部)。使用test('process')有时似乎有效,但可能会在十次调用中的一次中崩溃Matlab。如何在Matlab调用的mex函数中使用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); 
    } 
} 
+0

我认为[这个链接](http://www.mathworks.com/matlabcentral/newsreader/view_thread/45742)或一些这些[线程安全的Matlab引擎API](http://stackoverflow.com/questions/248421/thread-safety-of-matlab-engine-api)。这听起来像过程,而不是线程是要走的路。 – macduff 2012-03-07 15:14:11

+0

这些链接中的问题是多线程问题,即从多个线程访问Matlab引擎或Matlab函数。在我上面的例子中,每个引擎只能被一个线程访问,但它仍然不起作用。 – snowape 2012-03-07 16:38:40

+0

只是一个想法。你有没有尝试调用任何内置的Matlab工具进行多线程?例如'batch'命令,或者启动一个'timer',你可以定期运行一个回调函数。 – mattgately 2012-03-08 14:29:26

回答

0

如果它仍然是一个问题,我编你的代码,而该螺纹部分(仅“进程2”情况),没有错误,没有熄火,没有问题。 即

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

运行良好。我在一台Windows机器上,用Visual Studio 2010.

尽管如此,显然通过mex处理Matlab引擎的特性。在这个链接,你可以找到一个最近类似的情况,我有,和一个解决方法: http://www.mathworks.com/matlabcentral/newsreader/view_thread/327157#898916