主要内容

编写线程安全的S-Functions指南

金宝app®让你S-functions运行在多线程编程的同时,使模拟运行比串行运行更快。多线程编程与S-functions要求你S-functions线程安全的。创建线程安全的代码涉及到确保数据在多个线程之间共享保护数据和结果如预期。模拟与S-functions不是线程安全的可能会导致意想不到的行为。

背景

C / c++实现S-functions内置在C或c++和共享库称为墨西哥人文件。当一个功能块指的是一个共享库,MATLAB®加载功能块的过程。当多个功能块引用同一个共享库,也指最初的共享库副本。这个过程导致了多个功能模块共享相同的数据属于共享库。因此,多线程功能块同时访问相同的数据。

此外,如果这些S-functions指相同的资源,多线程功能块可以访问相同的资源(例如文件)同时,即使不同S-functions相关联的功能块。

的指导方针

一个功能通常被认为是线程安全的,可以放心地使用多个线程并发执行。指定一个函数是线程安全的,使用ssSetRuntimeThreadSafetyCompliance函数。如果你不确定你的s函数的线程安全,使用这些指导方针来调查和线程安全的。

数据共享

定义 问题 解决方案

使用指针功能指的是数据(例如,ssSetUserData,ssGetUserData,ssSetPWorkValuessGetPWorkValue)。一个使用这些指针函数轻松地共享数据。

多个线程可以使用指针来访问相同的数据。如果线程试图写相同的内存位置同时,他们违反了线程安全。从多个线程并发读取是安全的,只要没有写之前,期间,或读取后,会导致不连贯的缓存。

由多个线程访问共享数据时小心谨慎。

  • 使数据常数如果是只读的。

  • 控制对数据的访问,考虑使用互斥锁。互斥锁也可以确保缓存一致性。

全局变量

定义 问题 解决方案

在应用程序共享数据访问的全局变量。

多个线程写不共享数据是不安全的。阅读是安全的,只要没有写之前,期间,或读取后,会导致不连贯的缓存。

  • 如果您正在编写全局数据,定位,控制使用互斥访问它,或者改变你的算法的语义。以确保缓存一致性,也可以考虑使用内存栅栏等原子或互斥。

  • 如果你正在阅读,使你的全局变量不变。

局部静态变量初始化

定义 问题 解决方案

局部静态变量存储在一个位置。

  • 在c++中,局部静态变量初始化后进入功能范围和不是线程安全的。

  • 在C语言中,局部静态变量初始化应用程序的开始,只要右边的值的赋值(被分配到变量)的值是编译时常量。这些变量是线程安全的。

如果多个线程进入函数范围同时,软件使多个试图写入相同的位置。这个问题是即使局部静态变量是恒定的。

  • 如果您使用的是一个c++版本c++ 11之前,保护当地的初始化静态变量使用互斥或线程安全的初始化机制,如std:: call_onceboost:: call_once

  • 如果您正在使用c++ 11或后,局部静态变量初始化是保证线程安全的。

资源

定义 问题 解决方案

资源实体显式地请求并返回到系统。资源的一些例子包括动态分配的内存、文件、数据库连接、网络套接字。您的应用程序可能需要管理资源。

从多个线程访问资源可能不是线程安全的,比如从多个线程读取和写入到一个文件。即使这些操作都是线程安全的,他们可能不会产生预期的结果。

管理资源时小心谨慎。资源的线程安全取决于它的实现。关于线程安全规范的更多信息,请参见资源文档。可选地,您可以使用一种机制保护访问资源,比如互斥。

可重入性

定义 问题 解决方案

函数是可重入的,如果它是安全的从同一个线程调用多次(递归)。例如,strtok函数是不可重入的,因为它使一些内部状态的标记化的字符串。函数是可重入的,如果它不叫nonreentrant功能。

从多个线程调用nonreentrant函数可能不安全。

让你可重入函数。例如:

  • 消除美国的函数。

  • nonreentrant函数调用替换为可重入的等价物。例如,替换strtokstrtok_r

mexCallMATLAB

定义 问题 解决方案

一个功能可能调用MATLAB使用mexCallMATLAB函数。

金宝app仿真软件的代码处理mexCallMATLAB功能不是线程安全的。

不叫mexCallMATLAB你的功能。

除了免费代码

定义 问题 解决方案

一个功能异常是免费的,只要它的子程序,调用时,长跳的潜力。关于异常的更多信息自由S-functions,明白了除了免费代码

当一个功能免费也不例外,它的子程序是间接地通过mexCallMATLAB,这不是线程安全的mexCallMATLAB)。

检查你的长跳转功能。如果没有,将s函数标记为异常免费使用SS_OPTION_EXCEPTION_FREE_CODE ssSetOptions(年代)函数。如果s函数长跳尽管这个标志,不可预知的行为发生。

如果一个函数抛出一个异常,但使用try / catch块来捕获异常,这一功能是安全的。

数据竞赛

定义 问题 解决方案

数据竞赛发生在您的应用程序的输出取决于执行的顺序,这样应用程序之间的更改执行的行为。

应用程序可能意想不到的行为。

考虑下列之一:

  • 修改你的算法来消除数据竞争。

  • 使用锁来控制代码的关键部分的执行顺序,或制定关键操作原子。

挥发性

定义 问题 解决方案

挥发性关键字不告诉编译器优化变量,因为它的值可能会改变一些机制,编译器不知道。

应用程序可能错误地使用挥发性实现线程安全。挥发性不提供原子性或线程之间的同步。

不使用挥发性线程安全的关键字。

错误状态

定义 问题 解决方案

S-functions使用ssSetErrorStatus,ssGetErrorStatus,ssSetLocalErrorStatus,ssGetLocalErrorStatus访问错误状态。

ssSetErrorStatusssGetErrorStatus不是线程安全的。这些函数可以覆盖现有的错误,导致报告不准确的错误。例如,阻止可能会报告错误扔块B。

使用线程安全的ssSetLocalErrorStatus,ssGetLocalErrorStatus功能。不要使用ssSetErrorStatusssGetErrorStatus

另请参阅

|

相关的话题