2012-03-07 220 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