0% found this document useful (0 votes)
95 views6 pages

Multithreading in C-MEX for MATLAB

The document describes how to create threads from a C MEX file in MATLAB. It provides an example C code that creates multiple threads using pthreads when a MEX function is called. Each thread sleeps for a few seconds before exiting. When run with 6 threads, the output shows each thread starting and stopping sequentially over time. It is possible to create threads from MEX files as long as the threads do not access MATLAB and only use standard C functions.

Uploaded by

Mihaela Nistor
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
95 views6 pages

Multithreading in C-MEX for MATLAB

The document describes how to create threads from a C MEX file in MATLAB. It provides an example C code that creates multiple threads using pthreads when a MEX function is called. Each thread sleeps for a few seconds before exiting. When run with 6 threads, the output shows each thread starting and stopping sequentially over time. It is possible to create threads from MEX files as long as the threads do not access MATLAB and only use standard C functions.

Uploaded by

Mihaela Nistor
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Put the following code in a file with the name threads.

c
#include < pthread.h > /* for threading */
#include < unistd.h > /* for sleep */
#include "mex.h"
#include "matrix.h"

void *do_thread(void *threadid)


{
int tid;
tid = (int)threadid;
mexPrintf("In thread: just started thread #%d\n", tid);
sleep(4); /* pretend that the code is busy for a few seconds */
mexPrintf("In thread: about to exit from thread #%d\n", tid);
pthread_exit(NULL);
}

void mexFunction (int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[])
{
int num;

if (nrhs<1)
mexErrMsgTxt("not enough input arguments");
else
num = mxGetScalar(prhs[0]);

pthread_t threads[num];
int rc, t;
for(t=0; t < num ; t++){
mexPrintf("In main: creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL, do_thread, (void *)t);
if (rc){
mexErrMsgTxt("problem with return code from pthread_create()");
}
sleep(1); /* wait some time before making the next thread */
}
return;
}

Subsequently, in MATLAB you should compile the mex file using the following command:
>> mex threads.c -lpthread

After that, you can run the mex function. It takes a single argument, corresponding to the number
of threads to create. Each thread will live for three seconds (pretending that it is busy for some
time), and the time between threads being created is one second. Some example output is below.
>> threads(6)
In main: creating thread 0
In thread: just started thread #0
In main: creating thread 1
In thread: just started thread #1
In main: creating thread 2
In thread: just started thread #2
In main: creating thread 3
In thread: just started thread #3
In thread: about to exit from thread #0
In main: creating thread 4
In thread: just started thread #4
In thread: about to exit from thread #1
In main: creating thread 5
In thread: just started thread #5
In thread: about to exit from thread #2
>> In thread: about to exit from thread #3
In thread: about to exit from thread #4
In thread: about to exit from thread #5
>>

You can see each thread starting and stopping. The last threads stop after the control has been
returned to the MATLAB prompt.

Technical Solutions
Is it possible to start new threads from a C-MEX file?
Subject:

Is it possible to start new threads from a C-MEX file?

Problem Description:

I would like to start new execution threads from within a C-MEX file. Is this functionality
supported?

Solution:

There is no supported implementation of calling a single session of MATLAB in


separate threads. However, it is possible to create new threads from a C MEX-file in a
supported fashion; as long as those threads do not access MATLAB in any way.
Since the MEX API is not thread safe, no MEX API functions can be used in the
spawned threads including printf because printf is defined to be mexPrintf in the
mex.h header file.

Below are two examples of multithreaded MEX functions on Windows. You can also
create multithreaded MEX functions on other platforms, but the API functions for
creating threads will be different.

The following is an example of a C MEX-file that creates a new thread using the
function _beginthreadex. For details on this function, see:
http://msdn.microsoft.com/en-us/library/kdzttdcb(VS.80).aspx
The code below is adapted from the second example from the link above. Note that
this example requires a Microsoft compiler.

#include "mex.h"
#include <windows.h>
#include <stdio.h>
#include <process.h>

unsigned Counter;
unsigned __stdcall SecondThreadFunc( void* pArguments )
{
while ( Counter < 1000000 )
Counter++;

_endthreadex( 0 );
return 0;
}

void mexFunction( int nlhs, mxArray *plhs[],


int nrhs, const mxArray*prhs[] )

{
HANDLE hThread;
unsigned threadID;

printf( "Creating second thread...\n" );

/* Create the second thread.*/


hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc,
NULL, 0, &threadID );

/* Wait until second thread terminates. If you comment out the


line
* below, Counter will not be correct because the thread has not
* terminated, and Counter most likely has not been incremented
to
* 1000000 yet.*/
WaitForSingleObject( hThread, INFINITE );
printf( "Counter should be 1000000; it is-> %d\n", Counter );
/* Destroy the thread object. */
CloseHandle( hThread );

return;
}
Save the code above into a file named create_thread.c. Then execute:
mex -setup
and choose a Microsoft compiler. Compile the C-MEX function with:
mex create_thread.c
If you execute the MEX-function from the MATLAB command line, you should see
the following screen output:
Creating second thread...
Counter should be 1000000; it is-> 1000000

It is also possible to have the second thread continue to execute even after the
function mexFunction has returned to the MATLAB command prompt. You can then
call back into mexFunction and get the results from the second thread.

In this second example, the first time the MEX function is called, pass in the
argument 'Init'. This will spawn a second thread. The second time the MEX function
is called pass in the argument 'Finish' (or any other string). This will print the counter
variable and clean up the thread.
#include "mex.h"
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <string.h>

/*These global variables will be accessible to both threads and will


exist
*in the MEX function through multiple calls to the MEX function */
static unsigned Counter;
static HANDLE hThread=NULL;

/*The second thread should not try to communicate with MATLAB at all.

*This includes the use of mexPrintf, which attempts to print to the


*MATLAB command window. */
unsigned __stdcall SecondThreadFunc( void* pArguments ) {
/* loop for 20 seconds */

while ( Counter < 20 ) {


Counter++;
Sleep( 1000L );
}

_endthreadex( 0 );
return 0;
}

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const


mxArray*prhs[]) {
unsigned threadID;
char *cmd;

/* check for proper number of arguments */


if(nrhs!=1)
mexErrMsgTxt("One input required.");
/* check to make sure the first input argument is a string */
if (!mxIsChar(prhs[0]))
mexErrMsgTxt("Input must be a string.");

/* get command from first input */


cmd = mxArrayToString(prhs[0]);

/* if command is "Init", start the thread, otherwise wait for


thread
* to complete */
if (!strcmp(cmd,"Init")) {

/* make sure thread was not started using "mex locked" state
*/
if (mexIsLocked())
mexErrMsgTxt("Thread already initialized.");
/* lock thread so that no-one accidentally clears function */
mexLock();

/* Create the second thread. */


mexPrintf( "Creating second thread...\n" );
Counter = 0;
hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc,
NULL, 0, &threadID );
}
else {
/* make sure that the thread was started using "mex locked"
status*/
if (!mexIsLocked())
mexErrMsgTxt("Thread not initialized yet."); /*This
function will return control to MATLAB*/

/* wait for thread to finish and get result */


WaitForSingleObject( hThread, INFINITE );
mexPrintf( "Counter should be 20; it is-> %d\n", Counter );

/* Destroy the thread object, free memory, and unlock mex. */


CloseHandle( hThread );
mexUnlock();
}
return;
}

Save the code above into a file named create_async.c. Then execute:
mex create_async.c
Execute the following command to spawn the second thread
create_async Init
and you should see the following message
Creating second thread...
Next, execute the following command to get the results
create_async Finish
The program will pause until the second thread has finished executing, this will be
approximately 20 seconds from the time the thread was created. You should then see
the following message
Counter should be 20; it is-> 20

You might also like