简体   繁体   English

Matlab Mex库生命周期

[英]Matlab Mex library lifecycle

Does anyone know what the matlab mex library lifecycle is? 有谁知道matlab mex库生命周期是什么? Specifically I am interested in the following: 具体来说,我对以下内容感兴趣:

  1. Is there a way to force the library to be loaded before invoking it? 有没有办法在调用它之前强制加载库?
  2. Is the library a singleton or are multiple instances loaded? 库是单例还是多个实例加载?
  3. Are there any hooks for initialization prior to invocation? 在调用之前是否有任何用于初始化的钩子?
  4. Is there a destructor hook/signal that can be intercepted when the library is unloaded for cleanup? 是否有一个析构函数挂钩/信号,可以在卸载库进行清理时截获?

I did an extensive search here and online and I could not find the answers to these questions. 我在这里和网上进行了广泛的搜索,但我找不到这些问题的答案。 My problem has some performance cost with initialization and I would like to avoid that if possible, without needing to write a service. 我的问题在初始化时有一些性能成本,我想尽可能避免这种情况,而无需编写服务。

A MEX file stays loaded until you clear it ( clear myMexFun or clear mex ) or quit MATLAB. MEX文件保持加载状态,直到您清除它( clear myMexFunclear mex )或退出MATLAB。

For pre-loading, all I can suggest is to call the function with no inputs or with nop-equivalent inputs. 对于预加载,我所能建议的是调用没有输入或具有nop等效输入的函数。 I have created simple code paths in my mexFunction s to handle such calls without error, the simplest example being if(!nrhs) return; 我在mexFunction创建了简单的代码路径来处理这样的调用而没有错误,最简单的例子是if(!nrhs) return; . Subsequent calls will not need to load the mexFunction from disk (or any other functions in shared libraries called by the MEX function) and you do not need to worry about initialization cost after that. 后续调用不需要从磁盘(或MEX函数调用的共享库中的任何其他函数)加载mexFunction ,之后您无需担心初始化成本。

Regarding initialization/cleanup, constructors/destructors, etc. I am not aware of any way to see what MATLAB is doing when loading or unloading the MEX file, but a MEX file is a regular shared library (ie DLL/SO) that just exports a single function ( mexFunction is the only entry point ), so, as Amro points out, you can implement a DllMain in Windows to define module and thread attach/detach operations (see the excellent example in his answer ). 关于初始化/清理,构造函数/析构函数等。我不知道有什么方法可以看到MATLAB在加载或卸载MEX文件时正在做什么 ,但MEX文件是一个常规的共享库(即DLL / SO),它只是导出单个函数( mexFunction是唯一的入口点 ),因此,正如Amro所指出的,您可以在Windows中实现DllMain来定义模块和线程附加/分离操作(请参阅他的答案中的优秀示例)。 I'm not aware of any other mechanisms for interacting with the library. 我不知道有任何其他与库交互的机制。

To perform tasks when the module unloads, you can use mexAtExit within mexFunction to register with MATLAB a function to call when the MEX function unloads (again, cleared or MATLAB exits). 要在模块卸载时执行任务,可以在mexFunction使用mexAtExit向MATLAB注册一个函数,以便在MEX函数卸载时再次调用(再次,清除或MATLAB退出)。 Simply define a static function in the global namespace and register it with mexAtExit . 只需在全局命名空间中定义static函数,并将其注册到mexAtExit The example provided by MATLAB (mexatexit.c) demonstrates closing a file stream that was opened within mexFunction , but not closed. MATLAB(mexatexit.c)提供的示例演示了关闭在mexFunction中打开mexFunction关闭的文件流。 You could also free persistent memory, close streams, etc. Here is a contrived example: 你也可以释放持久性内存,关闭流等。这是一个人为的例子:

mexDLLtext.cpp : 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...
}

When run: 运行时:

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

And you have some control over unloading of the file via mexLock and mexUnlock . 你可以通过mexLockmexUnlock控制文件的卸载。

What happens to the arguments (ie prhs , plhs ) when the function starts and returns to MATLAB is very well documented , on the other hand, so I guess that's not what you are asking about. 会发生什么情况的参数(即prhsplhs )当函数开始,并返回到MATLAB是非常有据可查的 ,而另一方面,所以我想这不是你问什么。

Regarding multiple instances, you could try using Sysinternals' Process Explorer (if using Window) to have a look at what loaded modules have threads running under MATLAB.exe. 关于多个实例,您可以尝试使用Sysinternals的Process Explorer (如果使用Window)来查看已加载的模块在MATLAB.exe下运行的线程。 I only ever see one instance of a (single threaded) MEX file in threads list no matter how many times or how fast I call the function. 我只在线程列表中看到一个 (单线程)MEX文件的实例 ,无论我调用该函数多少次或多快。 However, once back at the command line, you can do version -modules to see a list of loaded modules, as Amro suggested. 但是,一旦返回命令行,您可以执行version -modules以查看已加载模块的列表,如Amro所建议的那样。 The MEX file will still be there, and as with the list of threads visible by Process Explorer, I only ever see one instance of a MEX certain file. MEX文件仍然存在,并且与Process Explorer可见的线程列表一样,我只看到MEX某个文件的一个实例。

Thanks, Amro for the input. 谢谢,Amro的意见。 I'm interested to see even some more authoritative answers to these questions! 我很想看到这些问题的一些更权威的答案!

As I mentioned in the comments, in Windows you could implement DllMain entry point. 正如我在评论中提到的,在Windows中你可以实现DllMain入口点。 This is because MEX-file are just regular DLL files with different extension. 这是因为MEX文件只是具有不同扩展名的常规DLL文件。 Here is a minimal example: 这是一个最小的例子:

testDLL.cpp 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");
}

Here is how it works: 下面是它的工作原理:

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