1

ユーザーが処理に使用する Matlab 関数を登録できる Matlab から呼び出すことができる mex プログラムを作成したいと考えています。次に、プログラムはこの関数を使用して、別のプログラムからのデータをバックグラウンドで処理します。mex プログラムと外部プログラム間の通信は共有グローバル バッファーを介して行われ、ミューテックス ロックで追跡します。その部分は実際に機能しているようです。問題は、Matlab がシングル スレッドであり、ユーザーが Matlab で作業を続けることができるように、バックグラウンドでデータを処理したいことです。Matlab はシングル スレッドであるため、私の解決策は、新しいスレッドを作成し、そこから Matlab エンジンを起動することです。このために、Matlab から呼び出された mex ファイルから Matlab エンジンを呼び出す必要があります。これを実行しようとすると、プログラムは正常にビルドされますが、新しいエンジンを開こうとすると、Matlab がクラッシュします。以下のテスト例を使用すると、test('process2')Matlab が停止し、ctrl-c を使用すると Matlab がクラッシュします。を使用test('process')すると動作するように見えることがありますが、Matlab はおそらく 10 回の呼び出しのうちの 1 回でクラッシュします。

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

1 に答える 1

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

うまく走った。VisualStudio2010を使用しているWindowsマシンを使用しています。

それにもかかわらず、mexを介してMatlabエンジンを扱う際には明らかに特殊性があります。このリンクでは、私が最近経験した同様のケースと回避策を見つけることができます:http: //www.mathworks.com/matlabcentral/newsreader/view_thread/327157#898916

于 2013-03-01T17:20:24.227 に答える