簡體   English   中英

Matlab Mex庫生命周期

[英]Matlab Mex library lifecycle

有誰知道matlab mex庫生命周期是什么? 具體來說,我對以下內容感興趣:

  1. 有沒有辦法在調用它之前強制加載庫?
  2. 庫是單例還是多個實例加載?
  3. 在調用之前是否有任何用於初始化的鈎子?
  4. 是否有一個析構函數掛鈎/信號,可以在卸載庫進行清理時截獲?

我在這里和網上進行了廣泛的搜索,但我找不到這些問題的答案。 我的問題在初始化時有一些性能成本,我想盡可能避免這種情況,而無需編寫服務。

MEX文件保持加載狀態,直到您清除它( clear myMexFunclear 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 

你可以通過mexLockmexUnlock控制文件的卸載。

會發生什么情況的參數(即prhsplhs )當函數開始,並返回到MATLAB是非常有據可查的 ,而另一方面,所以我想這不是你問什么。

關於多個實例,您可以嘗試使用Sysinternals的Process Explorer (如果使用Window)來查看已加載的模塊在MATLAB.exe下運行的線程。 我只在線程列表中看到一個 (單線程)MEX文件的實例 ,無論我調用該函數多少次或多快。 但是,一旦返回命令行,您可以執行version -modules以查看已加載模塊的列表,如Amro所建議的那樣。 MEX文件仍然存在,並且與Process Explorer可見的線程列表一樣,我只看到MEX某個文件的一個實例。

謝謝,Amro的意見。 我很想看到這些問題的一些更權威的答案!

正如我在評論中提到的,在Windows中你可以實現DllMain入口點。 這是因為MEX文件只是具有不同擴展名的常規DLL文件。 這是一個最小的例子:

testDLL.cpp

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM