Как я могу использовать движок Matlab в мекс-функции, вызываемой из Matlab - PullRequest
1 голос
/ 07 марта 2012

Я хочу создать mex-программу, которую можно вызывать из Matlab, где пользователь может зарегистрировать функцию Matlab, которая будет использоваться для обработки.Затем программа будет использовать эту функцию для обработки данных, поступающих из другой программы в фоновом режиме.Связь между программой mex и внешней программой осуществляется через общий глобальный буфер, который я отслеживаю с помощью блокировок мьютекса.Эта часть на самом деле, кажется, работает.Проблема в том, что Matlab является однопоточным, и я хочу обрабатывать данные в фоновом режиме, чтобы пользователь мог продолжать работать с Matlab.Поскольку Matlab является однопоточным, мое решение состоит в том, чтобы создать новый поток и запустить из него движок Matlab.Для этого мне нужно вызвать движок Matlab из mex-файла, который вызывается из Matlab.Когда я пытаюсь сделать это, программа собирается нормально, но когда я пытаюсь открыть новый движок, Matlab вылетает.Используя приведенный ниже тестовый пример, если я вызываю программу (изнутри Matlab) с test('process2') Matlab останавливается, а при использовании ctrl-c происходит сбой Matlab.Иногда кажется, что использование test('process') работает, но сбивает 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 голосов
/ 01 марта 2013

Если это все еще вызывает беспокойство, я скомпилировал ваш код без части потока (только "process2" case) без ошибок, без остановки, без проблем.то есть

#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.

Тем не менее, есть определенные особенности, связанные с движком Matlab через mex.По этой ссылке вы можете найти недавний похожий случай, который у меня был, и обходной путь: http://www.mathworks.com/matlabcentral/newsreader/view_thread/327157#898916

...