matlab void,MatLab engine多线程

MatLab

engine在多线程使用时,由于其本身不是线程安全的,所以需要在同一个线程里创建和使用。比如用户想要在thread1里调用engOpen创建一个MatLab Engine,然后在thread2里利用创建的Engine来调用MatLab函数,这时会出现Engine函数调用无效,即使Engine指针仍然在thread2里正确存在着。

如下:

Class CMatlabMultiThread

{

Protected:

Engine *m_pEngine;

//global MatLab engine

pointer

Protected:

void Main_thread();

//caller function for MatLab in main

thread

static void

*entry_new_thread(void

*Param);

//start of subthread

void MatLab_Engine_function();

//in subthread

}

//caller function for MatLab in main

thread

void CMatlabMultiThread::Main_thread()

{

pthread_t thread_id;

m_pEngine = engOpen(NULL); //open a matlab engine

if (m_pEngine ==

NULL)

{

//Error! Fail to connect to MATLAB

engine.

// The plot function will be

disabled!

printf("Fail to open MATLAB

Engine!\n");

exit(0);

}

//this function starts a new thread

and pass this pointer as parameter into the entry func

pthread_create(&thread_id, NULL,

& CMatlabMultiThread::entry_new_thread,

this);

}

//start of subthread

Void * CMatlabMultiThread:: entry_new_thread (void *Param)

{

((CMatlabMultiThread *) Param)->

MatLab_Engine_function();

}

//in subthread

void CMatlabMultiThread::MatLab_Engine_function()

{

engEvalString(m_pEngine, figure);

//through matlab engine to call matlab

function ‘figure’ to creat a new figure

window

//although the pointer m_pEngine

exists and is valid here, it can not function properly

}

如果连同对Engine的初始化都在子线程里完成,比如在MatLab_Engine_function里,那么在子线程里指令执行完后,将释放掉子线程的资源,相当于刚调用完MatLab函数,就调用engClose,这样,诸如用MatLab绘图这样的操作将一闪而过,这不是我们想要的。

然而,如果如上这样在主线程里初始化MatLab

Engine,在子线程里找到Engine指针,然后操作。这时虽然指针存在,但是实际无法进行任何操作。原因可以参加以下网址:http://www.mathworks.com/matlabcentral/fileexchange/349。

我的经验是:

将以上代码改为如下所示:

Class CMatlabMultiThread

{

Protected:

Engine *m_pEngine;

//global MatLab engine

pointer

Protected:

void Main_thread();

//caller function for MatLab in main

thread

static void

*entry_new_thread(void

*Param);

//start of subthread

void MatLab_Engine_function();//in

subthread

}

//caller function for MatLab in main

thread

void CMatlabMultiThread::Main_thread()

{

pthread_t thread_id;

int

result;

if ( m_pEngine != NULL

)

{

//in case the engine already exists, close

it

result = engClose(m_pEngine);

m_pEngine = NULL;

}

m_pEngine = engOpen(NULL); //open a matlab

engine

if (m_pEngine ==

NULL)

{

//Error! Fail to connect to MATLAB

engine.

// The plot function will be

disabled!

printf("Fail to open MATLAB

Engine!\n");

exit(0);

}

pthread_create(&thread_id, NULL,

& CMatlabMultiThread::entry_new_thread,

this);

}

//start of subthread

Void * CMatlabMultiThread:: entry_new_thread (void *Param)

{

((CMatlabMultiThread *) Param)->

MatLab_Engine_function();

}

//in subthread

void CMatlabMultiThread::MatLab_Engine_function()

{

//start a MatLab engine again, it dose

not make sense though, but works

m_pEngine =

engOpen(NULL);

if (m_pEngine ==

NULL)

{

//Error! Fail to connect to MATLAB

engine.

// The plot function will be

disabled!

printf("Fail to open MATLAB

Engine!\n");

exit(0);

}

engEvalString(m_pEngine, figure);

//through matlab engine to call matlab

function ‘figure’ to creat a new figure

window

}

即,在主线程里初始化一次MatLab Engine,然后在子线程里再初始化一次。另外,在主线程中调用engOpen之前,先调用一次engClose,这在多次调用MatLab函数中很有用。

虽然这看起来似乎说不通。在调试中可以看到,主线程里调用engOpen时,指针m_pEngine值比如是0x00d01730,此时可以看到MatLab Command Window已经打开。而在子线程里再次调用engOpen时,指针m_pEngine值会变为0x00d01740,m_pEngine值变化了,但是MatLab Command Window还是同一个。然后在函数MatLab_Engine_function中执行

engEvalString(m_pEngine, figure);

创建出一个MatLab绘图窗口。到子线程执行结束后,MatLab绘图窗口和MatLab Command Window都仍然存在。等再次调用主线程Main_thread执行

result = engClose(m_pEngine);

之前可以看到,m_pEngine值仍为0x00d01740,执行之后,返回值result为1,即关闭MatLab

Engine失败,但是MatLab

Command Window和MatLab绘图窗口却都正确的被关闭了,执行engClose(m_pEngine)后,m_pEngine值仍然为0x00d01740,所以为了以后不出现bug,设置为NULL。

看似不应该出现的情况,出现了,而且经严格测试,工作良好。那么,说明这么做一定是有道理的。所以,可以作为MatLab在多线程应用中的一种标准模式。当然,如果谁有更深刻的理解,或更有道理的作法,欢迎致信skpsun@163.com,或直接在日志下面留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值