Этот пример требует библиотеки POSIX-потоков (pthread) и, следовательно, запускается только на UNIX® платформы. Это простой многопоточный пример, в котором не используются постоянные или глобальные данные. Два потока вызывают MATLAB® функциональные matrix_exp
с различными наборами входных данных.
Чтобы вызвать входящий код, укажите main
функция, которая:
Включает заголовочный файл matrix_exp.h
.
Для каждого потока выделяет память для данных стека.
Вызывает matrix_exp_initialize
функции домашнего хозяйства. Дополнительные сведения см. в разделе Развертывание сгенерированного кода.
Вызовы matrix_exp
.
Вызовы matrix_exp_terminate
.
Освобождает память, используемую для данных стека.
В данном примере main.c
содержит:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include "matrix_exp.h" #include "matrix_exp_initialize.h" #include "matrix_exp_terminate.h" #include "rtwtypes.h" #define NUMELEMENTS (160*160) typedef struct { real_T in[NUMELEMENTS]; real_T out[NUMELEMENTS]; matrix_expStackData* spillData; } IODATA; /* The thread_function calls the matrix_exp function written in MATLAB */ void *thread_function(void *dummyPtr) { IODATA *myIOData = (IODATA*)dummyPtr; matrix_exp_initialize(); matrix_exp(myIOData->spillData, myIOData->in, myIOData->out); matrix_exp_terminate(); } int main() { pthread_t thread1, thread2; int iret1, iret2; IODATA data1; IODATA data2; int32_T i; /*Initializing data for passing to the 2 threads*/ matrix_expStackData* sd1=(matrix_expStackData*)calloc(1,sizeof(matrix_expStackData)); matrix_expStackData* sd2=(matrix_expStackData*)calloc(1,sizeof(matrix_expStackData)); data1.spillData = sd1; data2.spillData = sd2; for (i=0;i<NUMELEMENTS;i++) { data1.in[i] = 1; data1.out[i] = 0; data2.in[i] = 1.1; data2.out[i] = 0; } /*Initializing the 2 threads and passing required data to the thread functions*/ printf("Starting thread 1...\n"); iret1 = pthread_create(&thread1, NULL, thread_function, (void*) &data1); if (iret1 != 0){ perror( "Thread 1 creation failed."); exit(EXIT_FAILURE); } printf("Starting thread 2...\n"); iret2 = pthread_create(&thread2, NULL, thread_function, (void*) &data2); if (iret2 != 0){ perror( "Thread 2 creation failed."); exit(EXIT_FAILURE); } /*Wait for both the threads to finish execution*/ iret1 = pthread_join(thread1, NULL); if (iret1 != 0){ perror( "Thread 1 join failed."); exit(EXIT_FAILURE); } iret2 = pthread_join(thread2, NULL); if (iret2 != 0){ perror( "Thread 2 join failed."); exit(EXIT_FAILURE); } free(sd1); free(sd2); printf("Finished Execution!\n"); exit(EXIT_SUCCESS); } |
Чтобы сгенерировать код, запустите следующий скрипт в командной строке MATLAB.
% This example can only be run on Unix platforms if ~isunix error('This example requires pthread libraries and can only be run on Unix.'); end % Setting the options for the Config object % Create a code gen configuration object cfg = coder.config('exe'); % Enable reentrant code generation cfg.MultiInstanceCode = true; % Set the post code generation command to be the 'setbuildargs' function cfg.PostCodeGenCommand = 'setbuildargs(buildInfo)'; % Compiling codegen -config cfg main.c matrix_exp.m -report -args ones(160,160) |
Этот скрипт:
Генерирует сообщение об ошибке, если пример не работает на платформе UNIX.
Создает объект строения кода для генерации исполняемого файла.
Включает MultiInstanceCode
опция для генерации переиспользуемого, повторно входящего кода.
Использует PostCodeGenCommand
опция, чтобы задать команду post генерация кода как setbuildargs
функция. Эта функция устанавливает -lpthread
флаг, чтобы указать, что сборка включает библиотеку pthread.
function setbuildargs(buildInfo) % The example being compiled requires pthread support. % The -lpthread flag requests that the pthread library % be included in the build linkFlags = {'-lpthread'}; addLinkFlags(buildInfo, linkFlags);
Для получения дополнительной информации см. раздел Индивидуальную настройку процесса сборки.
Призывает codegen
со следующими опциями:
-config
для прохождения в объекте строения генерации кода cfg
.
main.c
чтобы включить этот файл в компиляцию.
-report
для создания отчета генерации кода.
-args
чтобы задать вход примера с классом, размером и сложностью.
codegen
генерирует заголовочный файл matrix_exp_types.h
, который определяет matrix_expStackData
глобальная структура. Эта структура содержит локальные переменные, которые являются слишком большими, чтобы помещаться в стек.
/* * matrix_exp_types.h * * Code generation for function 'matrix_exp' * */ #ifndef __MATRIX_EXP_TYPES_H__ #define __MATRIX_EXP_TYPES_H__ /* Include files */ #include "rtwtypes.h" /* Type Definitions */ #ifndef typedef_matrix_expStackData #define typedef_matrix_expStackData typedef struct { struct { double F[25600]; double Y[25600]; double X[25600]; } f0; } matrix_expStackData; #endif /*typedef_matrix_expStackData*/ #endif /* End of code generation (matrix_exp_types.h) */ |
Вызовите код с помощью команды:
system('./matrix_exp')
Управление использованием пространства стека | Распределение стека и эффективность