unix 天线接收信号原理理

新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
UID7799291空间积分0 积分122阅读权限10帖子精华可用积分122 信誉积分18 专家积分0 在线时间5 小时注册时间最后登录
白手起家, 积分 122, 距离下一级还需 78 积分
帖子主题精华可用积分122 信誉积分18 专家积分0 在线时间5 小时注册时间最后登录
论坛徽章:0
我要实现的就是发送一个信号(不管是用脚本还是程序),然后用我的QT写的程序来接受这个信号。
这个要怎么做呢??
谁能给点提示呢???
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
UID空间积分0 积分137337阅读权限100帖子精华可用积分137337 信誉积分2545 专家积分55 在线时间4631 小时注册时间最后登录
帖子主题精华可用积分137337 信誉积分2545 专家积分55 在线时间4631 小时注册时间最后登录
论坛徽章:11
那就用 kill 发信号吧
I can explain it for you, but I can’t understand it for you.
UID7799291空间积分0 积分122阅读权限10帖子精华可用积分122 信誉积分18 专家积分0 在线时间5 小时注册时间最后登录
白手起家, 积分 122, 距离下一级还需 78 积分
帖子主题精华可用积分122 信誉积分18 专家积分0 在线时间5 小时注册时间最后登录
论坛徽章:0
哦,那发出来的信号
我的QT程序要怎么接收呢?这之间要怎么连接呢??
进程间通信问题我刚接触,不是太明白
问的问题太小白了,多多见凉!
UID7799291空间积分0 积分122阅读权限10帖子精华可用积分122 信誉积分18 专家积分0 在线时间5 小时注册时间最后登录
白手起家, 积分 122, 距离下一级还需 78 积分
帖子主题精华可用积分122 信誉积分18 专家积分0 在线时间5 小时注册时间最后登录
论坛徽章:0
我使用 kill -10 “进程号”
我这样发送一个信号,但是要怎么接收呢??
我在我的QT程序中用什么来接受这个10的信号呢?
UID空间积分0 积分137337阅读权限100帖子精华可用积分137337 信誉积分2545 专家积分55 在线时间4631 小时注册时间最后登录
帖子主题精华可用积分137337 信誉积分2545 专家积分55 在线时间4631 小时注册时间最后登录
论坛徽章:11
参见 apue2 中和信号相关的章节
I can explain it for you, but I can’t understand it for you.
麦田守望者
UID7353309空间积分0 积分1145阅读权限2帖子精华可用积分1145 信誉积分175 专家积分10 在线时间261 小时注册时间最后登录
帖子主题精华可用积分1145 信誉积分175 专家积分10 在线时间261 小时注册时间最后登录
论坛徽章:0
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
UID空间积分0 积分32阅读权限10帖子精华可用积分32 信誉积分0 专家积分0 在线时间1 小时注册时间最后登录
白手起家, 积分 32, 距离下一级还需 168 积分
帖子主题精华可用积分32 信誉积分0 专家积分0 在线时间1 小时注册时间最后登录
论坛徽章:0
int kill(pid_t pid, int signo);
int raise(int signo);
kill 外部给你发信号
raise 进程自己给自己发信号
[ 本帖最后由 chinaunixbear 于
17:58 编辑 ]
UID34002空间积分8 积分1418阅读权限30帖子精华可用积分1418 信誉积分114 专家积分0 在线时间634 小时注册时间最后登录
家境小康, 积分 1418, 距离下一级还需 582 积分
帖子主题精华可用积分1418 信誉积分114 专家积分0 在线时间634 小时注册时间最后登录
论坛徽章:0
UID空间积分0 积分62阅读权限10帖子精华可用积分62 信誉积分0 专家积分0 在线时间186 小时注册时间最后登录
白手起家, 积分 62, 距离下一级还需 138 积分
帖子主题精华可用积分62 信誉积分0 专家积分0 在线时间186 小时注册时间最后登录
论坛徽章:0
你可以简单的用signal函数来定义信号对应的接收函数,用法man一下就知道了
新版本的信号发送和接收通过sigqueue和sigaction来实现,不过旧版本的也没什么问题
UID7201775空间积分0 积分19493阅读权限100帖子精华可用积分19493 信誉积分768 专家积分80 在线时间3204 小时注册时间最后登录
帖子主题精华可用积分19493 信誉积分768 专家积分80 在线时间3204 小时注册时间最后登录
认证徽章论坛徽章:3
原帖由 wangbenqq 于
11:32 发表
我要实现的就是发送一个信号(不管是用脚本还是程序),然后用我的QT写的程序来接受这个信号。
这个要怎么做呢??
谁能给点提示呢???
兄弟,万事不如靠自己,好好研读APUE2的信号那一张,一切问题都能搞明白了。
Nothing is impossible!
Nginx源码分析交流群:
微博地址:/u/Unix环境高级编程笔记 :10、信号 - 看引擎 KENGINE | 看看新闻网 IT资讯
Unix环境高级编程笔记 :10、信号
信号是软件中断,信号提供了一种处理异步事件的方法。
1、信号概念
每个信号都有一个名字,这些名字都以三个字符SIG开头。
SIGABRT是夭折信号,当进程调用abort函数时产生这种信号
SIGALRM是闹钟信号,当由alarm函数设置的计时器超时后产生此信号。
在头&signal.h&中,这些信号都被定义为正整数(信号编号).
很多条件可以产生信号 :
a)当用户按某些终端键时,引发终端产生信号
ctrl+c产生中断信号(SIGINT)
b)硬件异常产生信号:除数为0、无效内存引用
对执行一个无效内存引用的进程产生SIGSEGV
c)进程调用kill(2)函数可将信号发送给另一个进程或进程组
d)kill(1)命令将信号发送给其他进程
e)当检测到某种软件条件已经发生,并应将其通知有关进程时也产生信号。
信号是异步事件,产生信号的事件对进程而言是随机出现的。进程不能简单的测试一个变量来判断是否出现一个信号,而是必须告诉内核
“在此信号出现时,请执行下列操作。”
可以要求内核在某个信号出现时按照下列三种方式之一进行处理,我们称之为信号的处理
(1)忽略此信号
二种信号决不能被忽略:SIGKILL SIGSTOP
(2)捕捉信号
(3)执行系统默认动作
每一种信号的默认动作。注,针对大多数信号的系统默认动作是终止进程。
在“默认动作”列中,“终止+core”表示在进程当前工作目录的core文件中复制该进程的存储映象
#include &signal.h&
void (*signal(int signo,void (*func)(int))) (int);
#include &stdio.h&
#include &unistd.h&
#include &signal.h&
static void sig_usr(int signo);
int main(int argc, char **argv) {
if(signal(SIGUSR1,sig_usr) == SIG_ERR)
printf(“signal error”);
if(signal(SIGUSR2,sig_usr) == SIG_ERR)
printf(“signal error”);
static void sig_usr(int signo) {
if(signo == SIGUSR1) {
printf(“recived sigusr1″);
if(signo == SIGUSR2) {
printf(“recived sigusr2″);
printf(“recived %d”,signo);
kill -SIGUSR1 11251
kill -SIGUSR2 11251
程序启动:
1)当执行一个程序时,所有信号的状态都是系统默认或忽略,通常所有信号都被设置为它们的默认动作,除非调用exec的进程忽略该信号。
一个具体的例子是一个交互式shell如何处理针对后台进程的中断和退出信号
cc main.c &
shell自动将后台进程对中断和退出信号的处理方式设置为忽略。于是按中断键时不会影响到后台进程。
很多捕捉这二个信号的交互式程序具有下列形式的代码 :
void sig_int(int),sig_quit(int);
if(signal(SIGINT,SIG_IGN) != SIG_IGN)
signal(SIGINT,sig_int);
if(signal(SIGQUIT,SIG_IGN) != SIG_IGN)
signal(SIGQUIT,sig_quit);
2)进程创建
当一个进程调用fork时,其子进程继承父进程的信号处理方式。因为子进程在开始时复制了父进程的存储映像,所以信号捕捉函数的地址在子进程中是有意义
3、可重入函数
进程捕捉到信号并对其进行处理时,进程正在执行的指令序列就被信号处理程序临时中断,它首先执行该信号处理程序中的指令。
如果从信号处理程序返回,则继续执行在捕捉到信号时进程正执行的正常指令序列。
若信号处理程序中调用一个不可重入函数,则其结果是不可预见的。
4、可靠信号术语
1)当引发信号的事件发生时,为进程产生一个信号。可件可以是硬件异常、软件条件(alarm计时器超时)、终端产生的信号或调用kill。
2)当对信号采取了这种动作时,我们说向进程递送了一个信号。
3)在信号产生(generation)和递送(delivery)之间的时间间隔内,称信号是未决的(pending)
4)进程可以选用信号递送阻塞
5)进程调用sigpending判断哪些信号是设置为阻塞并处于未决状态
6)每个进程都有一个信号屏蔽字(signal mask),它规定了当前要阻塞递送到该进程的信号集。
7)sigset_t,保存一个信号集,信号屏蔽字就存放在这些信号集中
5、kill raise
kill函数将信号发送给进程或进程组。raise函数则允许进程向自身发送信号
#include &signal.h&
int kill(pid_t pid,int signo);
int raise(int signo);
raise(signo) 等价于kill(getpid(),signo);
将该信号发送给进程ID为pid的进程
pid==0 将该信号发送给与发送进程属于同一进程组的所有进程
将该信号发送给其进程组ID等于pid的绝对值,而且发送进程具有向其发送信号的权限。
pid==-1将该信号发送给发送进程有权限向它们发送信号的系统上的所有进程。
6、alarm和pause
使用alarm函数可以设置一个计时器,在将来某个指定的时间该计时器会超时。当计时器超时时,产生SIGALRM信号。
如果不忽略或不捕捉此信号,则其默认动作是终止调用该alarm函数的进程。
#include &unistd.h&
unsigned int alarm(unsigned int seconds);
参数seconds的值是秒数,经过了指定的seconds秒后产生信号SIGALRM。
pause函数使调用进程挂起直至捕捉到一个信号。
#incude &unistd.h&
int pause(void);
我们需要有一个能表示多个信号—信号集(signal set)的数据类型。
sigset_t表示一个信号集
#include &signal.h&
int sigemptyset(sigset_t *set);
//初始化由set指向的信号集,清除其中所有信号
int sigfillset(sigset_t *set);
//初始化由set指向的信号集,使其包括所有信号
int sigaddset(sigset_t *set,int signo);
int sigdelset(sigset_t *set,int signo);
8、sigprocmask函数
sigprocmask可以检测或更改其信号屏蔽字,或者在一个步骤中同时执行这二个操作。
#include &signal.h&
int sigprocmask(int how,const sigset_t *restrict set,siset_t #restrict oset);
9、sigpending
sigpending函数返回信号集,其中的各个信号对于调用进程是阻塞的而不能递送,因而也一定是当前未决的。
#include &signal.h&
int sigpending(sigset_t *set);
10、sigaction
sigaction函数的功能是检查或修改与指定信号相关的处理动作。
#include &signal.h&
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
11、sigsetjmp
siglongjmp
用于非局部转移的setjmp和longjmp,在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回。
调用longjmp有一个问题,当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动地加到进程的信号屏蔽字中。
这阻止了后来产生的这种信号中断该信号处理程序。
#include &setjmp.h&
int sigsetjmp(sigjmp_buf env, int savesigs);
void siglongjmp(sigjmp_buf env, int val);
如果savemask非0,则sigsetjmp在env中保存进程的当前信号屏蔽字。
调用setlongjmp时,如果带非0 savemask的sigsetjmp调用已经保存了env,则siglongjmp从其中恢复保存的信号屏蔽字。
12、sigsuspend
14、system
声明:OSCHINA 博客文章版权属于作者,受法律保护。未经作者同意不得转载。
No tags for this post.
除非注明,本站文章均为原创或编译,转载请注明: 文章来自
分享给朋友:
查看全部:您所在的位置: &
深入解析HP unix系统下Oracle两种集群模式原理(1)
深入解析HP unix系统下Oracle两种集群模式原理(1)
姚建伟 唐磊
中国软件评测中心
近日,由于项目中的需要对HP UNIX下的Oracle的集群模式进行了研究。Oracle拥有VG共享存储模式和独占模式两种集群模式,本文结合在实际项目,详细介绍了实现oracle数据库服务器的双机热备和动态负载均衡的过程。
近日,由于项目中的需要对HP UNIX下的Oracle的集群模式进行了研究。Oracle拥有VG共享存储模式和独占模式两种集群模式,本文结合在实际项目,详细介绍了实现oracle数据库服务器的双机热备和动态负载均衡的过程,具体如下:
1、双机热备(VG共享存储模式)及负载均衡方案
双机热备的含义就是设置两台互为备份的服务器,并且在同一时间内只有一台服务器运行。当出现意外情况时候,其中一台运行着的服务器出现意外故障而无法启动时,另一台备份的服务器就会自动的并迅速的启动运行,从而保证整个应用系统的正常运行。双机热备的工作机制实际上是为整个网络系统的中心服务器提供了一种故障自动恢复能力。
这里需要清楚阵列盘信息、双机软件信息、HP unix双机系统集群技术层次构架、负载均衡和单点故障自动切换:
1)阵列盘就是盘阵上的硬盘,就是双机热备要用到的物理存储。
2)操作系统双机软件:roseha,IBM的AIX小机的HACMP,HP-UNIX的SG(MC/service guard)。windows的mscs等等。这里用HP-UNIX的SG(service guard)。
3)oracle数据库集群软件Serviceguard Extension for RAC
4)HP unix双机系统集群技术层次构架由HP unix 11.31操作系统、HP UX service guard 集群组件、Oracle数据库集群等三部分组成,请看示意图&HP unix双机系统集群技术层次构架&。
a)HP unix 11.31操作系统重要信息内容是由系统内核和卷组管理器组成。在安装数据库集群软件(Serviceguard Extension for RAC)和操作系统集群软件(service guard)的时候,需要修改HP unix的内核参数信息,所以这里信息比较重要。
b)MC/service guard 是HP RX系列服务器的高可用性集群,在计算机软硬件出现故障时候,可以继续执行应用系统服务,是一种基于应用的可迁移方法。
c)卷组管理器是管理阵列盘,就是盘阵上的硬盘,就是双机热备要用到的物理存储。在HP UX系统中对应关系是这样:LUN--VG(逻辑磁盘)--对应多个LV(逻辑卷),并挂在文件系统和未格式化裸设备(raw device)--共享存储裸设备(shared raw device)。
图 1 HP unix双机系统集群技术层次构架
5)本次实施负载均衡方案是建立在加强网络数据处理能力,自动调节应用服务对两台节点上数据库的响应请求,分别对共享存储数据的读写服务操作,实现增加数据吞吐量和提高效率。
6)单点故障自动切换:2台主机(node1:40、node2:42)连接共享裸设备存储,同时只有一台主机对一个物理设备进行读写操作。系统定时发送heartbeat信息,一旦node1发生故障,系统自动切换到node2上。
首先进行相应的网络规划,每台主机需要有4个局域网IP和2个私有IP,公共ip地址和浮动ip地址要在同一网段。如下表:
随后以本次双机集群设置为例(如图示:集群硬件故障时-单点故障自动切换示意图-正常状态),node1包含一个应用服务包、一个浮动IP(node1-vip)和若干系统进程及应用占用的硬盘。同样,node 2也包含一个应用服务包、一个浮动IP(node2-vip)和若干系统进程及应用占用的硬盘。node1-vip、node2-vip地址是固定的,node1、node2可以保证各自稳定的为前端用户提供服务所对应的数据服务。同时,集群系统中没有任何一台机器都在时刻运行,没有闲置,各自运行自己的应用,资源利用得到合理配置,性能得到最大发挥。
如果node1在集群系统中出现软硬件或者网络故障,MC/service guard自动将程序包控制权转移给node2。保证应用服务继续进行,同时所有负载压力加载到node2上。(如图示:集群硬件故障时-单点故障自动切换示意图-切换状态)
图2 集群硬件故障时-单点故障自动切换示意图(正常状态)&
图3 集群硬件故障时-单点故障自动切换示意图(切换状态)
内容导航&第 1 页: &第 2 页: &第 3 页: &第 4 页: &第 5 页:
关于&&的更多文章
Java EE(以前叫做Java 2平台,企业版)是一个为支持企业级应用
网友评论TOP5
联想扬天V470G-ISE(H)笔记本采用酷睿i7-2630QM四核处理器...
传说中的“世界末日”即将来临,企业往往比较重视灾难
Windows Phone 与Nokia手机的结合于2012年初首次在大
SAP创始人哈索教授在本书中提出了创新的概念:高性能
本书综合介绍了微软的Windows Server 2003操作系统和微软其他常用应用软件提供的服务,同时融入了作者在Windows网络管理上的多年
51CTO旗下网站Unix下C(十五)——并发Socket程序设计
1. 非阻塞并发模型&&& I/O阻塞是影响进程并发的重要原因,进程一旦进入阻塞,就不能再执行任何操作。比如进程调用输入函数后,在默认情况下必须一直阻塞直到产生满足条件的数据为止。&&& 套接字也是一种I/O设备,它有四类阻塞性交易,分别是输入类交易(read、recv和recvfrom)、输出类交易(write和send等)、连接申请交易(connect)和连接处理交易(accept),其中UDP协议数据发送函数sendto不产生阻塞。&&& 当套接字调用以上函数时,将导致进程阻塞。因此把套接字函数的阻塞模式更改为非阻塞模式,是实现并发套接字程序的一种方法。&&& (1)非阻塞套接字系统调用&&&&&& 函数fcntl设置套接字描述符的O_NONBLOCK标志后,即可将I/O方式更改为非阻塞方式。此时如果调用输入函数、输出函数或者连接处理函数&&& (accept)的条件不满足,将立即返回-1并置errno为EAGAIN错误;如果连接申请函数(connect)的条件不满足时,将返回-1并置errno为&&& EINPROGRESS错误。& &&&&&& int nType = fcntl(nSock, F_GETFL, 0);&&&&&& fcntl(nSock, F_SETGL, nType | O_NONBLOCK);&&& (2)非阻塞套接字程序设计流程&&&&&& 非阻塞套接字程序一般包含一段循环代码,在循环中采用轮询的方式,分别调用套接字的输入、输出、申请连接或连接处理函数,从而达到并&&& 发。处理多个套接字的目的。非阻塞方式并发模型在应用上有一定的局限性。&&& 2.& 信号驱动并发模型&&&& 在信号驱动I/O模式下,进程可以一边做其他的事,一边等待信号。当文件描述符就绪时,Unix内核会向进程发送SIGIO信号(某些系统是SIGPOLL信号),进程获取该信号并调用预先准备的处理函数执行I/O操作。当函数调用完毕后,进程回到接收信号前的代码处继续工作。&&&& (1)信号驱动设计流程&&&&&&& 在一个套接字上实现信号驱动的步骤如下:&&&&&&& 步骤1:为信号SIGIO设计处理函数并捕获信号&&&&&&&&&&&&&& /*信号处理函数*/&&&&&&&&&&&&&& void func(int sig){&&&&&&&&&&&&&&&&&&&& ........................&&&&&&&&&&&&&&&&&&&& singnal(SIGIO, func);&&&&&&&&&&&&&& }&&&&&&&&&&&&&& .......................&&&&&&&&&&&&&& /*捕获信号SIGIO*/&&&&&&&&&&&&&& signal(SIGIO, func);&&&&&&& 步骤2:设定套接字的归属主,设置接收SIGIO信号的进程或进程组。一般情况下可以通过函数fcntl的F_SETOWN命令设置&&&&&&&&&&&&&& fcntl(nSock, F_SETOWN, getpid());&&& /*设置接收信号的进程*/&&&&&&&&&&&&&& 或者&&&&&&&&&&&&&& fcntl(nSock, F_SETOWN, 0 - getpgrp());& /*设置接收信号的进程组*/&&&&&&& 步骤3:设置套接字的异步I/O属性。一般情况下可以通过函数fcntl的F_SETFL命令设置。&&&&&&&&&&&&&& int nType;&&&&&&&&&&&&&& nType = fcntl(nSock, F_GETFL, 0);&&&&&&&&&&&&&& fcntl(nSock, F_SETFL, nType | O_ASYNC);&&&& 为了防止信号丢失,请务必保证先设置SIGIO信号的处理函数,再使用函数fcntl设置套接字的属主。&&&& (2)信号驱动应用范围&&&&&&& 套接字信号驱动的设置非常简单,但在实践中却难以实现。因为Unix内核并不仅仅在套接字有输入时才发送SIGIO信号,在套接字连接、输&&&& 出、错误和其他状态变化时均发送该信号,这样就直接导致了进程在接收信号后无法正确的判断下一步的行为。&&&&&&& 在UDP协议上执行套接字的信号驱动相对比较简单。仅在套接字收到了数据报和套接字发生了异步错误的情况下才会产生SIGIO信号。当UDP&&&& 异步套接字进程接收到虚拟号SIGIO时,只需要调用函数recvfrom读取数据报数据或是异步I/O的错误信息即可。&&&&&&& 如果在TCP写一下执行套接字的信号驱动,将会有太多的机会接收到SIGIO信号,以致于用户无法通过该信号正确地判断套接字当前所处的状& && 态。以下情况均能产生SIGIO信号:& & & & 侦听套接字调用accept来成功建立一个新连接;套接字连接成功后结束;套接字的某个通道(发送通道或是接收通道)被关闭;套接字接收到& && 了数据包;套接字发送了数据报;套接字发生了异步错误。&&& 【实践经验】信号驱动并发套接字模型可以应用于以下方面:&&&& (1)UDP服务器端进程。进程在接收到SIGIO信号后,直接调用函数recvfrom即可,比如网络时间协议NTP服务器。&&&& (2)TCP服务端套接字侦听程序。由于侦听套接字一般不涉及到数据的输入输出,故当进程接收到信号SIGIO时,一般意味着客户端发起了连接申&&&&&&& 请,此时直接调用函数accept即可。3.& 超时并发模型&&&& 超时也是防止阻塞的一种手段,他可以保证进程不会被永远刮起。阻塞函数的超时时间决定了进程的并发度,超时时间越小,并发度越高,超时时间越大,则并发度越低。&&&& (1)通过套接字选项设置超时&&&&&&& 可以通过套接字选项SO_SNDTIMEO和SO_RCVTIMEO分别设置套接字描述符伤的写入和读取操作的超时时间。但本方法有如下缺陷:&&&&&&&&&&& 只能设置套接字描述符上的读取和写入操作的超时时间,不能设置connect和accept等连接操作的超时。&&&&&&&&&&& 某些版本的Unix不支持这两个套接字选项。&&&& (2)通过信号SIGALRM设置超时&&&&&&& 在Unix下的阻塞函数一般都有在进程接收到任意信号后中断返回的传统,套接字函数也不例外,利用这个特性使用定时器信号SIGALRM实现&&&& 套接字的超时处理。下面是这种方法的常见设计流程,其中步骤1和步骤2是信号超时的准备工作,步骤3到6在调用超时函数的代码段中使用。&&&&&&& 步骤1:定义超时标志&&&&&&&&&&&&&& static int nTimeOut = 0;&&&&&&&&&&&&&& 静态整型变量nTimeOut代表函数超时,默认取值为0表示没有超时,取值为1时表示已经超时。&&&&&&& 步骤2:为信号SIGALRM设计处理函数。进程捕获定时器信号SIGALRM后将调用函数onTimeOut进行处理:&&&&&&&&&&&&&& void onTimeOut(int nSignal){&&&&&&&&&&&&&&&&&&& signal(nSignal, SIG_IGN);&&&&& /*超时一次后就忽略信号SIGALARM,防止循环超时*/&&&&&&&&&&&&&&&&&&& nTimeOut = 1;&&&&&&&&&&&&&&&&& /*设置超时标识为&已超时&*/&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&& 步骤3:捕获信号SIGALRM并设置定时器。&&&&&&&&&&&&&& signal(SIGALRM, onTimeOut);&& /*捕获信号SIGALRM*/&&&&&&&&&&&&&& alarm(TIMEOUT);&&&&&&&&&&&&&& /*TIMEOUT秒后发送定时器信号SIGALRM*/&&&&&&& 步骤4:调用套接字阻塞处理函数,比如套接字接收(recv,read,recvfrom)、发送(send,write)、连接申请(connect)或者接收连接&&&&&&&&&&&&&& (accept)等。&&&&&&& 步骤5:取消定时器并忽略信号SIGALRM&&&&&&&&&&&&&& alarm(0);&&&&&&&&&&&&&& signal(SIGALRM, SING_IGN);&&&&&&& 步骤6:函数返回,超时判断。&&&&&&&&&&&&&& if(nTimeOut == 1)&&&&&&&&&&&&&&&&&& /*超时处理*/&&&&&&&&&&&&&& else&&&&&&&&&&&&&&&&&& /*非超时处理*/&&&& (3)通过信号SIGALRM加跳转设置超时&&&&&&& 利用信号加跳转方式处理超时的原理与利用纯信号超时处理的原理非常类似,也是通过捕获定时器信号和判断超时标志变量来预防阻塞。不&&&& 同的是,前者采用跳转语句强行中止阻塞函数的执行,而后者则是利用函数本身在接收信号后中断返回的特性被动地中止阻塞函数的执行。&&&&&&& 这种方法的常见设计流程如下,其中步骤1和步骤2是信号超时的准备工作,步骤3到步骤7在调用超时函数的代码段中使用。&&&&&& 步骤1:定义超时标志和跳转结构。&&&&&&&&&&&&&& static int nTimeOut = 0;&&&&&&&&&&&&&& jmp_&&&&&& 步骤2:为信号SIGALRM设计处理函数。在处理函数中除了更改超时标志外,还增加了跳转语句。&&&&&&&&&&&& void onTimeOut(int nSignal){&&&&&&&&&&&&&&&& signal(nSignal, SIG_IGN);&& /*超时一次后就忽略信号SIGALARM,方式循环超时*/&&&&&&&&&&&&&&&& nTimeOut = 1;&&&&&&&&&&&&&& /*设置超时标识为&已超时&*/&&&&&&&&&&&&&&&& longjmp(env, 1);&&&&&&&&&&& /*语句跳转*/&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&& }&&&&&& 步骤3:记录跳转点。&&&&&&&&&&&& setjmp(env);&&&&&& 步骤4:超时判断。&&&&&& 步骤5:捕获喜好SIGALARM并设置定时器。&&&&&& 步骤6:调用套接字阻塞处理函数。&&&&&& 步骤7:取消定时器并忽略信号SIGALARM。4.& 多路复用并发模型&&&& 多路复用函数select把一些文件描述符集合在一起,如果某个文件描述符的状态发生变化,比如进入&写就绪&或者&读就绪&状态,函数select会立即返回,并且通知进程读取或写入数据;如果没有I/O到达,进程将进入阻塞,直到函数select超时退出为止。&&&& 套接字也是文件,函数select也支持套接字描述符,并且可以应用在TCP协议和UDP协议的套接字中。利用多路复用,进程就可以同时监控多个套接字信息,在多个套接字上并发地执行操作。&&&& 几种常见的使用函数select的套接字进程如下:&&&& (1)交互式进程&&&&&&& 程序一边处理客户的交互式输入输出,一边使用套接字。多路复用标注输入、标注输出和套接字文件描述符。&&&& (2)多套接字进程&&&&&&& 程序同时使用侦听套接字和大量的连接套接字。&&&& (3)多协议进程&&&&&&& 程序同时使用TCP套接字和UDP套接字。&&&& (4)多服务进程&&&&&&& 程序同时应用多种服务,完成多种应用协议,比如inetd守护进程等。&&&& 套接字多路复用并发程序的设计流程如下:&&&& 步骤1:创建套接字文件描述符集合。&&&&&&&&&&& fd_&&&&&&&&&&&&& /*文件描述符集合*/&&&&&&&&&&& FD_ZERO(&fdset);&&&&&&&&&& /*清空集合中的元素*/&&&&&&&&&&& FD_SET(nLisSock, &fdset);& /*监控侦听套接字*/&&&&&&&&&&& FD_SET(nSockVar, &fdset);& /*监视连接套接字*/&&&& 步骤2:准备超时时间。&&&&&&&&&&&&&&&&&&& /*定义超时时间*/&&&&&&&&&&& wait.tv_sec = 0;&&&&&&&&&&&& /*超时时间0.1秒*/&&&&&&&&&&& wait.tv_usec = 100000;&&&& 步骤3:调用函数select并检测应答结果。 & & & & &&& 假设只复用读集合中的套接字描述符,其中MAXSOCK是集合fdset中最大的描述符号。& & & & & && & & & & & ret = select(MAXSOCK + 1, &fdset, NULL, NULL, &wait);& & & & & & if(ret == 0) ............ &&&&&&&&& /*超时*/& & & & & & else if(ret == -1) .......... &&&&& /*错误*/&&&&&&&&&&& else ................&&&&&&&&&&&&&& /*产生了套接字连接或数据发送请求*/&&&& 步骤4:检测给套接字文件描述符的状态并处理之。&&&&&&&&&&& 如果是侦听套接字,其操作流程一般为:&&&&&&&&&&& if(FD_ISSET(nLisSock, &fdset)){&&&&&&&&&&&&&&&& if((nSockVar = accept(nLisSock, NULL, NULL)) & 0)&&&&&&&&&&&&&&&&&&&&&& ......................&&&&&&&&&&& }&&&&&&&&&&& 如果是连接套接字操作,其流程一般为:&&&&&&&&&&&
if(FD_ISSET(nSockVar, &fdset)){
&&&&&&&&&&&&&&&& read(nSockVar[i], buf, sizeof(buf));
&&&&&&&&&&&&&&&&&&&&&& ......................
&&&&&&&&&&& }5.& 多进程并发模型6.& inetd守护进程
&&最后修改于
请各位遵纪守法并注意语言文明

我要回帖

更多关于 电视卫星信号接收器 的文章

 

随机推荐