WorkMode=0x02 计划任务执行结果0x2WorkMode++后,WorkMode为多少?

HAProxy+Keepalived高可用负载均衡配置_服务器应用_Linux公社-Linux系统门户网站
你好,游客
HAProxy+Keepalived高可用负载均衡配置
来源:Linux社区&
作者:wgkgood
前言* 随着负载均衡器的成熟,人们熟知的软件负载均衡如LVS、HAProxy,各方面性能不亚于硬件负载均衡,HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。
HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。
我们平时用的负载均衡LVS是基于四层,新型的大型互联网公司也在采用HAProxy,了解了haproxy大并发、七层应用等特点,那今天我们来研究一下HAProxy+Keepalived基于七层负载高可用负载均衡的配置。
一、系统环境:
系统版本:6.0 x86_64
HAProxy版本:1.4.21
Keepalived版本:1.2.1
Nginx版本:1.2.2
MASTER_IP:192.168.0.130
BACKUP_IP:192.168.0.131
VIP:192.168.0.133
WEB_1:192.168.0.134
WEB_2:192.168.0.135
二、HAProxy安装:
1)首先安装192.168.0.130上安装:
下载最新稳定版本:1.4.21
cd /usr/wget http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.21.tar.gz
tar xzf haproxy-1.4.21.tar.gz &&cd haproxy-1.4.21 &&make TARGET=linux26PREFIX=/usr/local/haproxy &&make install PREFIX=/usr/local/haproxy
安装完毕,在/usr/local/haproxy/目录下会看到三个目录:doc、sbin、share
2) 接下来配置HAProxy。
cd /usr/local/mkdir -p etc/
然后在/usr/local/haproxy/etc/下新建haproxy.cfg文件,这里拷贝haproxy配置文件:
log 127.0.0.1 local0
maxconn 65535
chroot /usr/local/haproxy
pidfile /usr/local/haproxy/haproxy.pid
log 127.0.0.1 local3
option httplog
option httpclose
option dontlognull
option forwardfor
option redispatch
maxconn 65535
balance source
stats uri /web-status
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen chinaapp.sinaapp.com
option httplog
log global
option httpchk HEAD /index.html HTTP/1.0
server web1 192.168.0.134:80 weight 5 check inter 2000 rise 2 fall 3
server web2 192.168.0.135:80 weight 5 check inter 2000 rise 2 fall 3
然后启动haproxy,如下执行启动命令:
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.cfg
[WARNING] 217/57) : Proxy 'chinaapp.sinaapp.com': in multi-process mode, stats will be limited to process assigned to the current request.
会提示如上信息,nbproc进程如果设置为1则不会提示,如果想去掉这个提示可以修改编译文件即可。 在源码配置src/cfgparse.c找到如下行
if (nbproc & 1) { if (curproxy-&uri_auth) { - Warning("Proxy '%s': in multi-process mode, stats will be limited to process assigned to the current request.\n",
+ Warning("Proxy '%s': in multi-process mode, stats will be limited to the process assigned to the current request.\n",
调整nbproc & 1数值即可。
相关资讯 & & &
& (03月11日)
& (10/17/:07)
& (03月22日)
& (03月03日)
& (03/30/:34)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款DeveWork.com 新版上线测试中!
本站小程序版(DeveWork极客)
赞助商广告
(11) (6) (6) (6) (4)
赞助商广告使用 GDB 调试多进程程序
GDB 是 linux 系统上常用的 c/c++ 调试工具,功能十分强大。对于较为复杂的系统,比如多进程系统,如何使用 GDB 调试呢?考虑下面这个三进程系统:进程Proc2 是 Proc1 的子进程,Proc3 又是 Proc2 的子进程。如何使用 GDB 调试 proc2 或者 proc3 呢?实际上,GDB 没有对多进程程序调试提供直接支持。例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号并终止。那么该如何调试子进程呢?其实我们可以利用GDB的特点或者其他一些辅助手段来达到目的。此外,GDB 也在较新内核上加入一些多进程调试支持。接下来我们详细介绍几种方法,分别是 follow-fork-mode 方法,attach 子进程方法和 GDB wrapper 方法。follow-fork-mode在2.5.60版Linux内核及以后,GDB对使用fork/vfork创建子进程的程序提供了follow-fork-mode选项来支持多进程调试。follow-fork-mode的用法为:set follow-fork-mode [parent|child]parent: fork之后继续调试父进程,子进程不受影响。child: fork之后调试子进程,父进程不受影响。因此如果需要调试子进程,在启动gdb后:(gdb) set follow-fork-mode child并在子进程代码设置断点。此外还有detach-on-fork参数,指示GDB在fork之后是否断开(detach)某个进程的调试,或者都交由GDB控制:set detach-on-fork [on|off]on: 断开调试follow-fork-mode指定的进程。off: gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态。注意,最好使用GDB 6.6或以上版本,如果你使用的是GDB6.4,就只有follow-fork-mode模式。follow-fork-mode/detach-on-fork的使用还是比较简单的,但由于其系统内核/gdb版本限制,我们只能在符合要求的系统上才能使用。而且,由于follow-fork-mode的调试必然是从父进程开始的,对于fork多次,以至于出现孙进程或曾孙进程的系统,例如上图3进程系统,调试起来并不方便。Attach子进程众所周知,GDB有附着(attach)到正在运行的进程的功能,即attach &pid&命令。因此我们可以利用该命令attach到子进程然后进行调试。例如我们要调试某个进程RIM_Oracle_Agent.9i,首先得到该进程的pid[root@tivf09 tianq]# ps -ef|grep RIM_Oracle_Agent.9i
00:00:00 RIM_Oracle_Agent.9i
0 06:10 pts/3
00:00:00 grep -i rim_oracle_agent.9i通过pstree可以看到,这是一个三进程系统,oserv是RIM_Oracle_prog的父进程,RIM_Oracle_prog又是RIM_Oracle_Agent.9i的父进程。[root@tivf09 root]# pstree -H 6722通过 pstree 察看进程启动GDB,attach到该进程用 GDB 连接进程现在就可以调试了。一个新的问题是,子进程一直在运行,attach上去后都不知道运行到哪里了。有没有办法解决呢?一个办法是,在要调试的子进程初始代码中,比如main函数开始处,加入一段特殊代码,使子进程在某个条件成立时便循环睡眠等待,attach到进程后在该代码段后设上断点,再把成立的条件取消,使代码可以继续执行下去。至于这段代码所采用的条件,看你的偏好了。比如我们可以检查一个指定的环境变量的值,或者检查一个特定的文件存不存在。以文件为例,其形式可以如下:void debug_wait(char *tag_file)
if (tag_file存在)
睡眠一段时间;
}当attach到进程后,在该段代码之后设上断点,再把该文件删除就OK了。当然你也可以采用其他的条件或形式,只要这个条件可以设置/检测即可。Attach进程方法还是很方便的,它能够应付各种各样复杂的进程系统,比如孙子/曾孙进程,比如守护进程(daemon process),唯一需要的就是加入一小段代码。GDB wrapper很多时候,父进程 fork 出子进程,子进程会紧接着调用 exec族函数来执行新的代码。对于这种情况,我们也可以使用gdb wrapper 方法。它的优点是不用添加额外代码。其基本原理是以gdb调用待执行代码作为一个新的整体来被exec函数执行,使得待执行代码始终处于gdb的控制中,这样我们自然能够调试该子进程代码。还是上面那个例子,RIM_Oracle_prog fork出子进程后将紧接着执行RIM_Oracle_Agent.9i的二进制代码文件。我们将该文件重命名为RIM_Oracle_Agent.9i.binary,并新建一个名为RIM_Oracle_Agent.9i的shell脚本文件,其内容如下:[root@tivf09 bin]# mv RIM_Oracle_Agent.9i RIM_Oracle_Agent.9i.binary
[root@tivf09 bin]# cat RIM_Oracle_Agent.9i
gdb RIM_Oracle_Agent.binary当fork的子进程执行名为RIM_Oracle_Agent.9i的文件时,gdb会被首先启动,使得要调试的代码处于gdb控制之下。新的问题来了。子进程是在gdb的控制下了,但还是不能调试:如何与gdb交互呢?我们必须以某种方式启动gdb,以便能在某个窗口/终端与gdb交互。具体来说,可以使用xterm生成这个窗口。xterm是X window系统下的模拟终端程序。比如我们在Linux桌面环境GNOME中敲入xterm命令:xterm就会跳出一个终端窗口:终端如果你是在一台远程linux服务器上调试,那么可以使用VNC(Virtual Network Computing) viewer从本地机器连接到服务器上使用xterm。在此之前,需要在你的本地机器上安装VNC viewer,在服务器上安装并启动VNC server。大多数linux发行版都预装了vnc-server软件包,所以我们可以直接运行vncserver命令。注意,第一次运行vncserver时会提示输入密码,用作VNC viewer从客户端连接时的密码。可以在VNC server机器上使用vncpasswd命令修改密码。[root@tivf09 root]# vncserver
New 'tivf09:1 (root)' desktop is tivf09:1
Starting applications specified in /root/.vnc/xstartup
Log file is /root/.vnc/tivf09:1.log
[root@tivf09 root]#
[root@tivf09 root]# ps -ef|grep -i vnc
00:08:46 Xvnc :1 -desktop tivf09:1 (root)
-httpd /usr/share/vnc/classes -auth /root/.Xauthority -geometry
-depth 16 -rfbwait 30000 -rfbauth /root/.vnc/passwd -rfbport 5901 -pn
00:00:00 vncconfig -iconic
0 01:23 pts/0
00:00:00 grep -i vnc
[root@tivf09 root]#Vncserver是一个Perl脚本,用来启动Xvnc(X VNC server)。X client应用,比如xterm,VNC viewer都是和它通信的。如上所示,我们可以使用的DISPLAY值为tivf09:1。现在就可以从本地机器使用VNC viewer连接过去:VNC viewer:输入服务器输入密码:VNC viewer:输入密码登录成功,界面和服务器本地桌面上一样:VNC viewer下面我们来修改RIM_Oracle_Agent.9i脚本,使它看起来像下面这样:#!/bin/sh
export DISPLAY=tivf09:1.0; xterm -e gdb RIM_Oracle_Agent.binary如果你的程序在exec的时候还传入了参数,可以改成:#!/bin/sh
export DISPLAY=tivf09:1.0; xterm -e gdb --args RIM_Oracle_Agent.binary $@最后加上执行权限[root@tivf09 bin]# chmod 755 RIM_Oracle_Agent.9i现在就可以调试了。运行启动子进程的程序:[root@tivf09 root]# wrimtest -l 9i_linux
Resource Type
Resource Label : 9i_linux
: mdstatus
Database Home
: /data/oracle9i/920
Instance Home
Instance Name
Opening Regular Session...程序停住了。从VNC viewer中可以看到,一个新的gdb xterm窗口在服务器端打开了gdb xterm 窗口[root@tivf09 root]# ps -ef|grep gdb
00:00:00 xterm -e gdb RIM_Oracle_Agent.binary
0 04:30 pts/2
00:00:00 gdb RIM_Oracle_Agent.binary
0 04:30 pts/0
00:00:00 grep gdb运行的正是要调试的程序。设置好断点,开始调试吧!注意,下面的错误一般是权限的问题,使用 xhost 命令来修改权限:xterm 错误[root@tivf09 bin]# export DISPLAY=tivf09:1.0
[root@tivf09 bin]# xhost +
access control disabled, clients can connect from any hostxhost + 禁止了访问控制,从任何机器都可以连接过来。考虑到安全问题,你也可以使用xhost + &你的机器名&。小结上述三种方法各有特点和优劣,因此适应于不同的场合和环境:follow-fork-mode方法:方便易用,对系统内核和GDB版本有限制,适合于较为简单的多进程系统attach子进程方法:灵活强大,但需要添加额外代码,适合于各种复杂情况,特别是守护进程GDB wrapper方法:专用于fork+exec模式,不用添加额外代码,但需要X环境支持(xterm/VNC)。
相关主题GDB 官方参考资料:更多 VNC 信息:
添加或订阅评论,请先或。
有新评论时提醒我
static.content.url=http://www.ibm.com/developerworks/js/artrating/SITE_ID=10Zone=LinuxArticleID=243910ArticleTitle=使用 GDB 调试多进程程序publish-date=现代挖机的work mode代表什么_百度知道
现代挖机的work mode代表什么
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
你的回答被采纳后将获得:
系统奖励15(财富值+成长值)+难题奖励20(财富值+成长值)
alex1970的春天
alex1970的春天
采纳数:1532
获赞数:3814
------工作模式,施工模式
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。Mouseover text to see original. Click the button below to return to the English version of the page.
Note: This page has been translated by MathWorks.
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.
Back to English
Select Language
Chinese Simplified
Chinese Traditional
Haitian Creole
Indonesian
Lithuanian
Portuguese
Vietnamese
MathWorks Machine Translation
The automated translation of this page is provided by a general purpose third party translator tool.
MathWorks does not warrant, and disclaims all liability for, the accuracy, suitability, or fitness for purpose of the translation.
DWork Vector ExamplesGeneral DWork VectorThe S-function
how to configure a DWork vector for use with the Simulink®
Coder™ product.
The Simulink model
this S-function to implement a simple accumulator. The following portion of the mdlInitializeSizes method
initializes the DWork vector and all code generation properties associated
with it.ssSetNumDWork(S, 1);
ssSetDWorkWidth(S, 0, 1);
ssSetDWorkDataType(S, 0, SS_DOUBLE);
/* I free any old setting and update */
id = ssGetDWorkRTWIdentifier(S, 0);
if (id != NULL) {
id = malloc(80);
mxGetString(ID_PARAM(S), id, 80);
ssSetDWorkRTWIdentifier(S, 0, id);
/* Type Q free any old setting and update */
tq = ssGetDWorkRTWTypeQualifier(S, 0);
if (tq != NULL) {
tq = malloc(80);
mxGetString(TQ_PARAM(S), tq, 80);
ssSetDWorkRTWTypeQualifier(S, 0, tq);
/* Storage class */
sc = ((int_T) *((real_T*) mxGetPr(SC_PARAM(S)))) - 1;
ssSetDWorkRTWStorageClass(S, 0, sc);The S-function initializes the DWork vector in mdlInitializeConditions.#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions ============================
* Abstract:
Initialize both continuous states to zero
static void mdlInitializeConditions(SimStruct *S)
real_T *x = (real_T*) ssGetDWork(S,0);
/* Initialize the dwork to 0 */
x[0] = 0.0;
}The mdlOutputs method assigns the DWork vector
value to the S-function output./* Function: mdlOutputs ========================================
* Abstract:
static void mdlOutputs(SimStruct *S, int_T tid)
real_T *y = ssGetOutputPortRealSignal(S,0);
real_T *x = (real_T*) ssGetDWork(S,0);
/* Return the current state as the output */
y[0] = x[0];
}The mdlUpdate method increments the DWork
value by the input.#define MDL_UPDATE
/* Function: mdlUpdate ============================================
* Abstract:
This function is called once for every major integration
time step. Discrete states are typically updated here, but
this function is useful for performing any tasks that should
only take place once per integration step.
static void mdlUpdate(SimStruct *S, int_T tid)
real_T *x = (real_T*) ssGetDWork(S,0);
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
* Increment the state by the input
* U is defined as U(element) (*uPtrs[element])
x[0] += U(0);
}DWork Scratch VectorThe following example uses a scratch DWork vector to store a
static variable value. The mdlInitializeSizes method
configures the width and data type of the DWork vector. The ssSetDWorkUsageType macro
then specifies the DWork vector is a scratch vector.ssSetNumDWork(S, 1);
ssSetDWorkWidth(S, 0, 1);
ssSetDWorkDataType(S, 0, SS_DOUBLE);
ssSetDWorkUsageType(S,0, SS_DWORK_USED_AS_SCRATCH);
The remainder of the S-function uses the scratch DWork vector
exactly as it would any other type of DWork vector. The InitializeConditions method
sets the initial value and the mdlOutputs method
uses the value stored in the DWork vector.#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions ================================ */
static void mdlInitializeConditions(SimStruct *S)
real_T *x = (real_T*) ssGetDWork(S,0);
/* Initialize the dwork to 0 */
x[0] = 0.0;
/* Function: mdlOutputs ============================================= */
static void mdlOutputs(SimStruct *S, int_T tid)
real_T *y = ssGetOutputPortRealSignal(S,0);
real_T *x1 = (real_T*) ssGetDWork(S,1);
x[0] = 2000;
y[0] = x[0] * 2;
}If you have Simulink
Coder, the Simulink
Coder software
handles scratch DWork differently from other DWork vectors when generating
code for inlined S-function. To inline the S-function, create the
following Target Language Compiler (TLC) file to describe the mdlOutputs method.%implements sfun_dscratch "C"
%% Function: Outputs ==========================================================
/* dscratch Block: %&Name& */
%&LibBlockDWork(DWork[0], "", "", 0)& = 2000.0;
%&LibBlockOutputSignal(0,"","",0)& = %&LibBlockDWork(DWork[0],"","", 0)& * 2;When the Simulink
Coder software generates code for the
model, it inlines the S-function and declares the second DWork vector
as a local scratch vector. For example, the model outputs function
contains the following lines:/* local scratch DWork variables */
real_T SFunction_DWORK1;
SFunction_DWORK1 = 2000.0;
If the S-function used a general DWork vector instead of a scratch
DWork vector, generating code with the same TLC file would have resulted
in the DWork vector being included in the data structure, as follows:sfcndemo_dscratch_DWork.SFunction_DWORK1 = 2000.0;DState Work VectorThis example rewrites the S-function example
use a DState vector instead of an explicit discrete state vector.
The mdlInitializeSizes macro initializes the number
of discrete states as zero and, instead, initializes one DWork vector.The mdlInitializeSizes method then configures
the DWork vector as a DState vector using a call to . This is equivalent
to calling the ssSetDWorkUsageType macro with the
value SS_DWORK_USED_AS_DSTATE. The mdlInitializeSizes method
sets the width and data type of the DState vector and gives the state
a name using ssSetDWorkName.static void mdlInitializeSizes(SimStruct *S)
ssSetNumSFcnParams(S, 0);
/* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
/* Parameter mismatch reported by the Simulink engine */
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
if (!ssSetNumInputPorts(S, 1))
ssSetInputPortWidth(S, 0, 2);
ssSetInputPortDirectFeedThrough(S, 0, 1);
if (!ssSetNumOutputPorts(S, 1))
ssSetOutputPortWidth(S, 0, 2);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 0);
ssSetNumIWork(S, 0);
ssSetNumPWork(S, 0);
ssSetNumModes(S, 0);
ssSetNumNonsampledZCs(S, 0);
ssSetNumDWork(S, 1);
ssSetDWorkUsedAsDState(S, 0, SS_DWORK_USED_AS_DSTATE);
ssSetDWorkWidth(S, 0, 2);
ssSetDWorkDataType(S, 0, SS_DOUBLE);
ssSetDWorkName(S, 0, "SfunStates");
ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
The mdlInitializeConditions method initializes
the DState vector values using the pointer returned by ssGetDWork.#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions ===============================
* Abstract:
Initialize both discrete states to one.
static void mdlInitializeConditions(SimStruct *S)
real_T *x0 = (real_T*) ssGetDWork(S, 0);
for (lp=0;lp&2;lp++) {
*x0++=1.0;
The mdlOutputs method then uses the values
stored in the DState vector to compute the output of the discrete
state-space equation./* Function: mdlOutputs ========================================
* Abstract:
y = Cx + Du
static void mdlOutputs(SimStruct *S, int_T tid)
= ssGetOutputPortRealSignal(S,0);
= (real_T*) ssGetDWork(S, 0);
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
UNUSED_ARG(tid); /* not used in single tasking mode */
/* y=Cx+Du */
y[0]=C[0][0]*x[0]+C[0][1]*x[1]+D[0][0]*U(0)+D[0][1]*U(1);
y[1]=C[1][0]*x[0]+C[1][1]*x[1]+D[1][0]*U(0)+D[1][1]*U(1);
Finally, the mdlUpdate method updates the
DState vector with new values for the discrete states.#define MDL_UPDATE
/* Function: mdlUpdate ============================================
* Abstract:
xdot = Ax + Bu
static void mdlUpdate(SimStruct *S, int_T tid)
tempX[2] = {0.0, 0.0};
= (real_T*) ssGetDWork(S, 0);
InputRealPtrsType uPtrs
= ssGetInputPortRealSignalPtrs(S,0);
UNUSED_ARG(tid); /* not used in single tasking mode */
/* xdot=Ax+Bu */
tempX[0]=A[0][0]*x[0]+A[0][1]*x[1]+B[0][0]*U(0)+B[0][1]*U(1);
tempX[1]=A[1][0]*x[0]+A[1][1]*x[1]+B[1][0]*U(0)+B[1][1]*U(1);
x[0]=tempX[0];
x[1]=tempX[1];
}DWork Mode VectorThis example rewrites the S-function
use a DWork mode vector instead of an explicit mode work vector (see
for more information
on mode work vectors). This S-function implements an absolute value
block.The mdlInitializeSizes method sets the number
of DWork vectors and zero-crossing vectors (see ) to DYNAMICALLY_SIZED.
The DYNAMICALLY_SIZED setting allows the Simulink engine
to defer specifying the work vector sizes until it knows the dimensions
of the input, allowing the S-function to support an input with an
arbitrary width.static void mdlInitializeSizes(SimStruct *S)
ssSetNumSFcnParams(S, 0);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
/* Parameter mismatch reported by the Simulink engine */
ssSetNumContStates(
ssSetNumDiscStates(
if (!ssSetNumInputPorts(S, 1))
ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED);
ssSetInputPortDirectFeedThrough(S, 0, 1);
if (!ssSetNumOutputPorts(S,1))
ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 0);
ssSetNumIWork(S, 0);
ssSetNumPWork(S, 0);
ssSetNumDWork(S, 1);
ssSetNumModes(S, 0);
/* Initializes the zero-crossing and DWork vectors */
ssSetDWorkWidth(S,0,DYNAMICALLY_SIZED);
ssSetNumNonsampledZCs(S, DYNAMICALLY_SIZED);
/* Take care when specifying exception free code - see sfuntmpl_doc.c */
ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}The Simulink engine initializes the number of zero-crossing
vectors and DWork vectors to the number of elements in the signal
coming into the first S-function input port. The engine then calls
the mdlSetWorkWidths method, which uses ssGetNumDWork to
determine how many DWork vectors were initialized and then sets the
properties for each DWork vector.#define MDL_SET_WORK_WIDTHS
static void mdlSetWorkWidths(SimStruct *S) {
int_T numdw = ssGetNumDWork(S);
for (i = 0; i & i++) {
ssSetDWorkUsageType(S, i, SS_DWORK_USED_AS_MODE);
ssSetDWorkDataType(S, i, SS_BOOLEAN);
ssSetDWorkComplexSignal(S, i, COMPLEX_NO);
The mdlOutputs method uses the value stored
in the DWork mode vector to determine if the output signal should
be equal to the input signal or the absolute value of the input signal.static void mdlOutputs(SimStruct *S, int_T tid)
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
= ssGetOutputPortRealSignal(S,0);
width = ssGetOutputPortWidth(S,0);
*mode = ssGetDWork(S,0);
UNUSED_ARG(tid); /* not used in single tasking mode */
if (ssIsMajorTimeStep(S)) {
for (i = 0; i & i++) {
mode[i] = (boolean_T)(*uPtrs[i] &= 0.0);
for (i = 0; i & i++) {
y[i] = mode[i]? (*uPtrs[i]): -(*uPtrs[i]);
}Level-2 MATLAB S-Function DWork VectorThe example S-function
a variable width pulse generator. The S-function uses two DWork vectors.
The first DWork vector stores the pulse width value, which is modified
at every major time step in the Update method.
The second DWork vector stores the handle of the pulse generator block
in the Simulink model. The value of this DWork vector does not
change over the course of the simulation.The PostPropagationSetup method, called DoPostPropSetup in
this S-function, sets up the two DWork vectors.function DoPostPropSetup(block)
% Initialize the Dwork vector
block.NumDworks = 2;
% Dwork(1) stores the value of the next pulse width
block.Dwork(1).Name
block.Dwork(1).Dimensions
block.Dwork(1).DatatypeID
block.Dwork(1).Complexity
= 'Real'; % real
block.Dwork(1).UsedAsDiscState =
% Dwork(2) stores the handle of the Pulse Geneator block
block.Dwork(2).Name
= 'BlockHandle';
block.Dwork(2).Dimensions
block.Dwork(2).DatatypeID
block.Dwork(2).Complexity
= 'Real'; % real
block.Dwork(2).UsedAsDiscState =
The Start method initializes the DWork vector
values.function Start(block)
% Populate the Dwork vector
block.Dwork(1).Data = 0;
% Obtain the Pulse Generator block handle
pulseGen = find_system(gcs,'BlockType','DiscretePulseGenerator');
blockH = get_param(pulseGen{1},'Handle');
block.Dwork(2).Data = blockH;
The Outputs method uses the handle stored
in the second DWork vector to update the pulse width of the Pulse
Generator block.function Outputs(block)
% Update the pulse width value
set_param(block.Dwork(2).Data, 'PulseWidth', num2str(block.InputPort(1).data));
The Update method then modifies the first
DWork vector with the next value for the pulse width, specified by
the input signal to the S-Function block.function Update(block)
% Store the input value in the Dwork(1)
block.Dwork(1).Data = block.InputPort(1).D
%endfunction
Was this topic helpful?
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window.
Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
(Fran?ais)
(Italiano)
Switzerland
Asia Pacific

我要回帖

更多关于 0x80070035 的文章

 

随机推荐