[英]Matlab Mex library lifecycle
有誰知道matlab mex庫生命周期是什么? 具體來說,我對以下內容感興趣:
我在這里和網上進行了廣泛的搜索,但我找不到這些問題的答案。 我的問題在初始化時有一些性能成本,我想盡可能避免這種情況,而無需編寫服務。
MEX文件保持加載狀態,直到您清除它( clear myMexFun
或clear mex
)或退出MATLAB。
對於預加載,我所能建議的是調用沒有輸入或具有nop等效輸入的函數。 我在mexFunction
創建了簡單的代碼路徑來處理這樣的調用而沒有錯誤,最簡單的例子是if(!nrhs) return;
。 后續調用不需要從磁盤(或MEX函數調用的共享庫中的任何其他函數)加載mexFunction
,之后您無需擔心初始化成本。
關於初始化/清理,構造函數/析構函數等。我不知道有什么方法可以看到MATLAB在加載或卸載MEX文件時正在做什么 ,但MEX文件是一個常規的共享庫(即DLL / SO),它只是導出單個函數( mexFunction
是唯一的入口點 ),因此,正如Amro所指出的,您可以在Windows中實現DllMain
來定義模塊和線程附加/分離操作(請參閱他的答案中的優秀示例)。 我不知道有任何其他與庫交互的機制。
要在模塊卸載時執行任務,可以在mexFunction
使用mexAtExit
向MATLAB注冊一個函數,以便在MEX函數卸載時再次調用(再次,清除或MATLAB退出)。 只需在全局命名空間中定義static
函數,並將其注冊到mexAtExit
。 MATLAB(mexatexit.c)提供的示例演示了關閉在mexFunction
中打開mexFunction
關閉的文件流。 你也可以釋放持久性內存,關閉流等。這是一個人為的例子:
mexDLLtext.cpp :
#include "mex.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
static FILE *fp=NULL;
static double *pDataC=NULL, *pDataCpp=NULL, *pMxData=NULL;
static char fName[L_tmpnam], counter = 0;
static void CleanUp(void)
{
fclose(fp); /* close file opened with fopen */
free(pDataC); /* deallocate buffer allocated with malloc/calloc */
delete[] pDataCpp; /* deallocate buffer allocated with new double[...] */
mxFree(pMxData); /* free data created with mx function like mxMalloc */
mexPrintf("Closing %s and freeing memory...\n",fName);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (!fp) { tmpnam(fName); fp = fopen(fName,"w"); }
fprintf(fp,"%d ",++counter);
if (!pDataC) pDataC = (double*) malloc(sizeof(double)*16);
if (!pDataCpp) pDataCpp = new double[16];
if (!pMxData) {
pMxData = (double*) mxMalloc(sizeof(double)*16);
mexMakeMemoryPersistent(pMxData); mexPrintf("First!\n");
}
mexAtExit(CleanUp);
// Then use the persistent data...
}
運行時:
>> mex -largeArrayDims mexDLLtest.cpp
>> for i=1:5, mexDLLtest; end
First!
>> clear mexDLLtest
Closing \s1rg.1 and freeing memory...
>> type E:\s1rg.1
1 2 3 4 5
你可以通過mexLock
和mexUnlock
控制文件的卸載。
會發生什么情況的參數(即prhs
, plhs
)當函數開始,並返回到MATLAB是非常有據可查的 ,而另一方面,所以我想這不是你問什么。
關於多個實例,您可以嘗試使用Sysinternals的Process Explorer (如果使用Window)來查看已加載的模塊在MATLAB.exe下運行的線程。 我只在線程列表中看到一個 (單線程)MEX文件的實例 ,無論我調用該函數多少次或多快。 但是,一旦返回命令行,您可以執行version -modules
以查看已加載模塊的列表,如Amro所建議的那樣。 MEX文件仍然存在,並且與Process Explorer可見的線程列表一樣,我只看到MEX某個文件的一個實例。
謝謝,Amro的意見。 我很想看到這些問題的一些更權威的答案!
正如我在評論中提到的,在Windows中你可以實現DllMain
入口點。 這是因為MEX文件只是具有不同擴展名的常規DLL文件。 這是一個最小的例子:
#include "mex.h"
#include <windows.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
mexPrintf("DLL_PROCESS_ATTACH: hModule=0x%x\n", hModule);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
mexPrintf("DLL_PROCESS_DETACH: hModule=0x%x\n", hModule);
break;
}
return TRUE;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mexPrintf("Inside MEX-function\n");
}
下面是它的工作原理:
>> mex -largeArrayDims testDLL.cpp
>> testDLL
DLL_PROCESS_ATTACH: hModule=0xa0980000
Inside MEX-function
>> testDLL
Inside MEX-function
>> clear testDLL
DLL_PROCESS_DETACH: hModule=0xa0980000
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.