可以从C-MEX文件启动新线程吗?

40次浏览(最近30天)
我想从C-MEX文件中启动新的执行线程。是否支持此功能?万博1manbetx

接受的答案

MathWorks支万博1manbetx持团队
编辑:MathWorks支万博1manbetx持团队 2020年11月4日
没有支持在单独的线程中调万博1manbetx用MATLAB的单个会话的实现。但是,可以以受支持的方式从C mex -文件创建新线程;万博1manbetx只要这些线程不以任何方式访问MATLAB。因为MEX API不是线程安全的,所以不能在派生的线程(包括printf)中使用MEX API函数,因为在MEX .h头文件中printf被定义为mexPrintf。
下面是Windows上的两个多线程MEX函数示例。您也可以在其他平台上创建多线程MEX函数,但是用于创建线程的API函数是不同的。
下面是一个使用_beginthreadex函数创建新线程的C mex文件示例。关于该函数的详细信息,请参见:
下面的代码改编自上面链接中的第二个示例。注意,这个例子需要一个Microsoft编译器。
包括“mex.h”
包括< windows.h >
包括< stdio . h >
包括< process.h >
无符号计数器
无符号__stdcall SecondThreadFunc(void* pArguments)
(计数器< 1000000)
计数器+ +;
_endthreadex (0);
返回0;
}
无效mxArray *plhs[], mxArray *plhs[],
intnrhs,常量mxArray * prhs [])
处理hThread;
无符号threadID;
printf (“创建第二个线程…\ n”);
/*创建第二个线程
hThread =(处理)_beginthreadadex (NULL, 0, &SecondThreadFunc, NULL, 0, & threaddid);
/*等待,直到第二个线程结束。如果注释掉该行
*, Counter将不正确,因为线程没有
*终止,并且Counter很可能没有被增加到
* 1000000。* /
WaitForSingleObject(hThread, INFINITE);
printf (“计数器应为100万;这是- > % d \ n”、计数器);
/*销毁线程对象。*/
CloseHandle (hThread);
返回
}
将上面的代码保存到名为create_thread.c的文件中。然后执行:\ n
墨西哥人设置
并选择一个微软编译器。用\n编译C-MEX函数
墨西哥人create_thread.c
如果您从MATLAB命令行执行mex函数,您应该看到以下屏幕输出
创建第二个线程...
计数器应为1000000;它是- > 1000000
即使在函数mexFunction返回到MATLAB命令提示符后,也可以让第二个线程继续执行。然后可以回调到mexFunction并从第二个线程获得结果。
在第二个例子中,第一次调用MEX函数时,传入参数'Init'。这将生成第二个线程。第二次调用MEX函数时,传入参数'Finish'(或任何其他字符串)。这将打印计数器变量并清除线程
包括“mex.h”
包括< windows.h >
包括< stdio . h >
包括< process.h >
包括< string.h >
/ *这些全球两个线程都可以访问变量,并且变量是存在的
*在通过多次调用MEX函数*/
静态无符号计数器
静态处理hThread =零
/ *第二线程根本不应该尝试与MATLAB通信。
*这包括mexPrintf的使用,这试图打印到
* MATLAB命令窗口。*/
无符号__stdcall SecondThreadFunc(void* pArguments) {
/ *循环20秒*/
(Counter < 20) {
计数器+ +;
睡眠(1000升);
}
_endthreadex (0);
返回0;
}
无效mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray*prhs[]) {
无符号threadID
字符* cmd
/ *检查适当的数量的参数* /
如果(nrhs ! = 1)
mexErrMsgTxt (“一个输入必需的。”);
/ *检查确保第一个输入参数是一个字符串*/
如果! mxIsChar (prhs [0]))
mexErrMsgTxt ("Input必须是一个字符串。");
/ *得到命令从第一个输入*/
cmd = mxArrayToString (prhs [0]);
/*如果命令“Init”,开始线程,否则等待的线程
*完成*/
如果“Init”)! strcmp (cmd) {
/ *确保线程没有使用"mex locked"状态启动
如果(mexIsLocked ())
mexErrMsgTxt (“线程已经初始化。”);
/ *锁的线程这样就不会有人意外地清除函数*/
mexLock ();
/ *创建第二个线程。*/
mexPrintf (“创建第二个线程…\ n”);
Counter = 0;
hThread =(处理)_beginthreadadex (NULL, 0, &SecondThreadFunc, NULL, 0, & threaddid);
}
其他的
/*确保线程是使用“墨西哥人锁定”状态* /
如果! mexIsLocked ())
mexErrMsgTxt (“线程尚未初始化。”);/ *这函数返回控制MATLAB * /
/ *等待线程完成并得到结果*/
WaitForSingleObject(hThread, INFINITE);
mexPrintf (“计数器应该是20;这是- > % d \ n”、计数器);
/ *摧毁线程对象,免费的内存,打开墨西哥人。*/
CloseHandle (hThread);
mexUnlock ();
}
返回
}
将上面的代码保存到名为create_async.c的文件中。然后执行:\ n
墨西哥人create_async.c
执行以下命令生成第二个线程\n
create_async初始化
你应该看到下面的消息\n
创建第二个线程...
接下来,执行以下命令获取结果\n
create_async完成
程序将暂停,直到第二个线程完成执行,这将从线程创建时间大约20秒。然后您应该看到以下消息\n
计数器应该是20;它- > 20

更多的答案(0)

社区寻宝

在MATLAB中心找到宝藏,并发现社区如何可以帮助你!

开始狩猎!