В этом примере требуются библиотеки потоков 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 для установки команды генерации посткодов в значение 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')Использование пространства стека элементов управления | Распределение стека и производительность