繁体   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