매트랩에서는 Thread를 지원하지 않는다.
그래서 C에서 Thread code를 작성한 후에 이를 mex compile해서 사용하고자 하는 것이 본 포스팅의 목적이다.
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <string.h>
/* 여기 있는 전역 변수들은 thread와 mexFunction 모두에 있어서 접근이 가능하다.
* 그렇기 때문에, thread에서 변경하고, matlab에서 읽을 수 있다.
*/
static unsigned Counter;
static HANDLE hThread=NULL;
/* Thread 함수이다. 이 함수를 matlab과 독립적으로 수행되어야만 한다.
*/
unsigned __stdcall SecondThreadFunc( void* pArguments ) {
/* loop for 20 seconds */
while ( Counter < 20 ) {
Counter++;
Sleep( 1000L );
}
_endthreadex( 0 );
return 0;
}
/*
* 이부분이 실제로 mex로 불릴 부분이다.
*/
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
{
unsigned threadID, i;
char *cmd;
double *outputDoublePtr, *inputDoublePtr;
/* Right-hand side Argument의 수를 확인한다. */
if(nrhs!=1)
mexErrMsgTxt("One input required.");
/* Argument는 string 이어야만 한다. (이 예제에선) */
/*
if (!mxIsChar(prhs[0]))
mexErrMsgTxt("Input must be a string.");
*/
/* Argument는 double 이어야만 한다. (이 예제에선) */
if (!mxIsDouble(prhs[0]))
mexErrMsgTxt("Input must be a double.");
/* 해당 argument를 처리할 수 있는 형식으로 읽어온다. */
// cmd = mxArrayToString(prhs[0]);
inputDoublePtr = mxGetPr(prhs[0]);
/*
* cmd에는 우리가 input으로 넣은 text가 들어있다.
*/
// if (!strcmp(cmd,"Init"))
if (inputDoublePtr[0] == 0)
{
/*
* 이미 Lock이 걸려 있다는 것은 Thread가 켜졌다는 의미이다.
* 그렇기 때문에 여기서 에러를 출력한다.
*/
if (mexIsLocked())
/* 에러를 출력하고 handle을 matlab으로 옮긴다. */
mexErrMsgTxt("Thread already initialized.");
/* 우리는 Thread를 키기 때문에 Lock을 거는 것이 중요하다. */
mexLock();
/* Counter를 초기화 한다. */
Counter = 0;
/* 드디어 Thread를 킨다. */
mexPrintf( "Creating Thread...\n" );
hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );
}
// else if (!strcmp(cmd,"test"))
else if (inputDoublePtr[0] == 1)
{
/* 중간에 Thread에서 돌고 있는 Counter를 확인할 수 있게 한다. */
mexPrintf( "Counter: %d sec \n", Counter );
}
else
{
/* Lock이 걸려있지 않다는 것은 Thread 역시 켜져있지 않다는 의미이다. */
if (!mexIsLocked())
mexErrMsgTxt("Thread not initialized yet."); /*This function will return control to MATLAB*/
/* Thread가 끝날 때 까지 기다린다. */
WaitForSingleObject( hThread, INFINITE );
mexPrintf( "Counter should be 20; it is-> %d\n", Counter );
/* Thread를 종료하고 Unlock한다. */
CloseHandle( hThread );
mexUnlock();
}
/* 출력할 것이 있을 때만 출력을 한다. */
if (nlhs == 1)
{
plhs[0] = mxCreateDoubleMatrix(1, 10, mxREAL);
/* Get Pointer for 출력 */
outputDoublePtr = mxGetPr(plhs[0]);
for( i = 0; i<10; i++)
outputDoublePtr[i] = i;
}
return;
}
위의 코드를 수행하는 matlab 코드는 다음과 같다.
clc;
clear all;
close all;
%% mex compile한다.
mex mex_thread.c
%% Thread 킨다.
a = mex_thread(0);
disp(a);
%% Thread 테스트
a = mex_thread(1);
disp(a);
%% Thread 종료 (초기화 하고 20초 후에 종료)
a = mex_thread(2);
disp(a);
'Enginius > Matlab' 카테고리의 다른 글
Get width and height automatically for SUBPLOT (get_wh4subplot) (0) | 2013.09.29 |
---|---|
Split structured TXT files (strsplit) (0) | 2013.09.29 |
Control Pioneer 3dx with MATLAB (0) | 2013.08.21 |
Automatic Color Distribution for Multiple Plot + Use Tex Equation in Plot (0) | 2013.08.09 |
keyDownListener + figCloseHandler + figTimer (0) | 2013.08.01 |