精华内容
下载资源
问答
  • Django信号系统简介

    千次阅读 2016-07-26 16:00:41
    django信号系统

    # django信号系统
    
    django自带一套信号发射系统来帮助我们在框架的不同位置传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)推送给一组接受者(receivers).信号系统在我们多处代码与同一个事件相关是特别有用.

    既然是信号系统,那么必须包含以下要素:

     1. 发送者-谁发送了信号

     2. 信号-发送的信号本身

     3. 接收者-信号是发给谁的

    创建信号

    想要发送信号,必须先要创建一个信号,在django中,信号是django.dispatch.Signal类的实例,该类的构造函数接受一个名叫providing_args参数,该参数是参数名列表,举例如下:

    
    import django.dispatch
    
    game_start = django.dispatch.Signal(providing_args=['player',  'level'])
    

    该段代码的意思是,生成一个在游戏开始时发送的信号,信号包含两个参数,游戏者,关卡.

    指定信号发送者

    有了信号,我们要确定信号是谁发送出去的,这个时候就要用到“`Signal.send(sender, **kwargs)方法了.代码示例以及解释如下:

    
    class Game(object):
    
        def start(self, user, level):
    
            game_start.send(sender=self.__class__, player=user, level=level)
    
            ......
    

    以上代码的意思是,在游戏启动的时候,游戏实例会发送一个之前定义的信号.信号包含了游戏者和关卡的信息.

    信号监听

    由于信号接受方不知道信号什么时候会传递过来,所以接收方一般是在做持续监听,收到信号就触发反应,没收到就一直待机.因此我们需要一个负责监听的方法.这个方法是Signal.connect(receiver, sender=None, weak=True, dispatch_uid=None)

    现在来解释一下最基本的参数:

    1. receiver: 信号接受者,回调函数

    2. sender: 信号发送者

    示例:

    
    game_start.connect(game_logger)
    

    开启监听之后,就要去实现回调函数了

    
    def game_logger():
    
        # log to log file
    
        print 'Done!'
    

    流程解释

    1. 首先我们创建了一个在游戏开始是发出的信号

    2. 在游戏开始时让指定的发送者发出信号

    3. 接受端一直处于监听状态,收到信号,调用回调函数,将游戏者和关卡信息写入日志

    展开全文
  • DTMF信号系统的Matlab仿真

    千次阅读 2020-10-29 00:51:28
    双音多频(Dual Tone Multi Frequency, DTMF)信号是音频电话中的拨号信号,由美国AT&T贝尔公司实验室研制,并用于电话网络中。这种信号制式具有很高的拨号... DTMF信号系统是一个典型的小型信号处理系统,它要...

            双音多频(Dual Tone Multi Frequency, DTMF)信号是音频电话中的拨号信号,由美国AT&T贝尔公司实验室研制,并用于电话网络中。这种信号制式具有很高的拨号速度,且容易自动检测识别,很快就代替了原有的用脉冲计数方式的拨号制式。这种双音多频信号制式不仅用在电话网络中,还可以用于传输十进制数据的其他通信系统中,用于电子邮件和银行系统中。这些系统中用户可以用电话发送DTMF信号选择语音菜单进行操作。

           DTMF信号系统是一个典型的小型信号处理系统,它要用数字方法产生模拟信号并进行传输,其中还用到了D/A变换器;在接收端用A/D变换器将其转换成数字信号,并进行数字信号处理。本文着重介绍了一种快速的频率检测算法——GEORTZEL算法的原理,以及该算法在双音多频拨号检测系统中的应用。并根据此算法设计出了相应的滤波器,利用MATLAB在计算机上对双音多频的信令产生及检测接收系统进行了仿真测试。

    双音多频(Dual Tone Multi FrequencyDTMF)信号,由美国AT&T贝尔实验室研制,用于音频电话网络中的拨号信号。一方面这种信号具有非常高的拨号速度,另一方面它便于自动检测识别及电话业务的拓展,所以很快代替了原有的脉冲计数方式的拨号形式。

    自1876年美国贝尔发明电话以来,电话交换技术发展主要经历了三个阶段:人工交换、机电交换、电子交换。早在1878年就出现了人工供电制交换机,它借助话务员进行话务连接。15年后步进制的交换机问世,这种交换机属于“直接控制”方式,用户通过话机拨号脉冲直接控制步进接续器做升降和旋转动作。从而自动完成用户间的接续。这种交换机虽然实现了自动接续,但存在着速度慢、效率低、杂音大与机械磨损严重等缺点。直到1938年发明了纵横制交换机由直接控制过渡到间接控制方式,随后又出现了电子交换机及程控交换机等。用户的拨号脉冲不再直接控制接线器动作,而先由记发器接收、存储,然后通过标志器驱动接线器,以完成用户间接续。由于标志器记取的是标识信号,所以可以不采用不稳定的脉冲计数方式,逐步发展到数字号码标识,所以快速、稳定灵活的DTMF音频拨号方式取代了脉冲计数方式。

    本文主要阐述GOERTZEL算法在双音拨号系统中的应用,并利用Matlab的强大功能,用软件实现DTMF(双音多频)信号的检测。

    1.2 数字信号简介

    信号是反映消息的物理量,是消息的表现形式。由于非电的物理量可以通过各种传感器较容易地转换成电信号,而电信号又容易传送和控制,所以使其成为应用最广的信号。电信号是指随着时间而变化的电压或电流,因此在数学描述上可将它表示为时间的函数,并可画出其波形。信息可以通过电信号进行传送、交换、存储、提取等。

    电信号的形式是多种多样的,可以从不同的角度进行分类。根据信号的随机

    性可以分为确定信号和随机信号;根据信号的周期性可分为周期信号和非周期信

    1

     

    号;根据信号的连续性可以分为连续时间信号和离散信号;在电子线路中将信号分为模拟信号和数字信号。

    我们每天遇到的信号,大部分都是模拟信号。离散时间信号只被定义在一种特定的时间瞬间集合上,表现为具有连续数值范围的数值序列。而数字信号在时间上和幅值上都有离散的数字。因此在实际的操作中,数字信号更容易处理。随着数字电子技术的发展,在语音处理、通信控制、图象处理等领域DSP(Digital Signal Processor 数字信号处理器 )也得到了越来越广泛的应用。

    数字通信抗干扰能力强、无噪声积累,由于数字信号的幅值为有限个离散值(通常取两个幅值),在传输过程中虽然也受到噪声的干扰,但当信噪比恶化到一定程度时,即在适当的距离采用判决再生的方法,再生成没有噪声干扰的和原发送端一样的数字信号,所以可实现长距离高质量的传输。

    较之传统的方法,数字信号处理系统自身有着无可比拟的优点:

    (1)便于加密处理

      信息传输的安全性和保密性越来越重要,数字通信的加密处理的比模拟通信容易得多,以话音信号为例,经过数字变换后的信号可用简单的数字逻辑运算进行加密、解密处理。

    (2)便于存储、处理和交换

      数字通信的信号形式和计算机所用信号一致,都是二进制代码,因此便于与计算机联网,也便于用计算机对数字信号进行存储、处理和交换,可使通信网的管理、维护实现自动化、智能化。

    (3)设备便于集成化、微型

      数字通信采用时分多路复用,不需要体积较大的滤波器。设备中大部分电路是数字电路,可用大规模和超大规模集成电路实现,因此体积小、功耗低。

    (4)便于构成综合数字网和综合业务数字网

      采用数字传输方式,可以通过程控数字交换设备进行数字交换,以实现传输和交换的综合。另外,电话业务和各种非话业务都可以实现数字化,构成综合业务数字网

     

    2

    (5)占用信道频带较宽

      一路模拟电话的频带为4kHz带宽,一路数字电话约占64kHz,这是模拟通信目前仍有生命力的主要原因。随着宽频带信道(光缆、数字微波)的大量利用以及数字信号处理技术的发展,数字电话的带宽问题已不是主要问题了。

     

    下面用MATLAB程序对该系统进行模拟,程序分四段:第一段(第2~7行)设置参数,并读入8位电话号码;第二段(第9~20行)根据输入的8位电话号码产生时域离散DTMF信号,并连续发出8位号码对应的双音频声音;第三段(第22~25行)对时域离散DTMF信号进行频率检测,画出幅度谱;第四段(第26~33行)根据幅度谱的两个峰值,分别查找并确定输入的8位电话号码。程序如下:

     

    17

    % DTMF双频拨号信号的生成和检测程序:

    %clear all;clc;

    tm=[1,2,3,65;4,5,6,66;7,8,9,67;42,0,35,68];   % DTMF信号代表的16个数

    N=205;K=[18,20,22,24,31,34,38,42];              %8个基频对应的8个k值

    f1=[697,770,852,941];                   % 行频率向量

    f2=[1209,1336,1477,1633];               % 列频率向量

    TN=input('键入8位电话号码= ');          % 输入8位数字

    TNr=0;                                  %接收端电话号码初值为零

    for l=1:8;                %分别对每位号码数字处理:产生信号,发声,检测

        d=fix(TN/10^(8-l));                   %计算出第l位号码数字

        TN=TN-d*10^(8-l);

        for p=1:4;

            for q=1:4;

                if tm(p,q)==abs(d); break,end     % 检测与l位号码相符的列号q

            end

    if tm(p,q)==abs(d); break,end     % 检测与l位号码相符的行号p

        end

        n=0:1023;                               % 为了发声,加长序列

        x = sin(2*pi*n*f1(p)/8000) + sin(2*pi*n*f2(q)/8000);% 构成双音频信号

        sound(x,8000);                               % 发出声音

        pause(0.1)                            %相邻信号响声之间加0.1秒停顿

        % 接收检测端的程序

        X=goertzel(x(1:N),K+1);            % 用Goertzel算法计算8点DFT样本

        val = abs(X);                           % 列出八点DFT的摸

        subplot(4,2,l);                                                     

        stem(K,val,'.');grid;xlabel('k');ylabel('|X(k)|') % 画出8点DFT(k)的幅度

        axis([10 50 0 120])

        limit = 80;                           %基频检测门限为80

        for s=5:8;

            if val(s) > limit, break, end       % 查找列号

        end

        for r=1:4;

            if val(r) > limit, break, end       % 查找行号

    end

    18

        TNr=TNr+tm(r,s-4)*10^(8-l);    %将8位号码表示成一个8位数,以便显示

    end

    disp('接收端检测到的号码为:')         % 显示接收到的8位电话号码

    disp(TNr)

     

    运行程序,根据提示输入8位电话号码12345678,回车后可以听见8位电话号码对应的DTMF信号的声音,并输出响应的频谱图,如图5-1所示。左上角的第一个图在k=18和k=31两点出现峰值,所以对应第一位号码数字1,依次类推,其他7幅图分别表示数字2,3,4,5,6,7,8对应的DTMF信号DFT的8点采样的幅度值。最后显示检测到的电话号码12345678,如图5-2所示。

    图5-1 8位电话号码12345678的DTMF信号在8个近似基频点的DFT幅度

     

    展开全文
  • 心电信号系统GUI系统

    千次阅读 2020-09-24 21:11:23
    ·由于本系统所要实现的功能较多,所以所有的功能按键均采用菜单形式进行设计。 ·整个系统的菜单如下所示: 下面介绍各个菜单的运行结果: STEP01:运行得到如下的界面 STEP02:导入ECG信号 STEP03...

    ·由于本系统所要实现的功能较多,所以所有的功能按键均采用菜单形式进行设计。

    ·整个系统的菜单如下所示:

          

     

    下面介绍各个菜单的运行结果:

    STEP01:运行得到如下的界面

    STEP02:导入ECG信号

     

    STEP03:对原信号加入噪声

     

    STEP04:信号的局部放大显示

    STEP05:左右移动,上下移动,幅度增大减小

    STEP06:还原为原信号

     

    STEP07:导出处理后的信号

     

    STEP08:原信号功率谱

     

    STEP09:计算心率

     

    STEP10IIR滤波器设计即滤波效果

    滤波效果:

     

    滤波之后的功率谱密度曲线。

     

    STEP11FIR滤波器设计即滤波效果

    STEP12:整数滤波器设计即滤波效果

    这个步骤操作方法和上面IIR相同。

    STEP13:加载已经设计好的滤波器系数

     

     

    STEP14:模拟ECG信号

     

     

     

    展开全文
  • Linux信号系统详解

    千次阅读 2012-11-18 22:25:29
    [Linux信号系统简介]  在Linux系统中,信号机制是在软件层次上对中断机制的一种模拟。一个进程接收到信号之后,有相应的信号的处理程序,而一个进程也可以给另外一个(或一组)进程发送信号。在内核版本的0.11...
    代码对应linux kernel v0.11

    [Linux信号系统简介]

         在Linux系统中,信号机制是在软件层次上对中断机制的一种模拟。一个进程接收到信号之后,有相应的信号的处理程序,而一个进程也可以给另外一个(或一组)进程发送信号。在内核版本的0.11版本中,每个进程都有一个结构体sigaction的数组,类似于系统的中断描述表(也被称为中断向量表),这个数组可以被称为进程的信号描述表(信号向量表)。但信号向量表和中断向量表之间是有区别的,中断向量表所对应的中断处理例程一般是内核中的相关函数,但信号向量表中的处理程序一般来自用户进程。
         对信号的检测与响应总是发生在系统空间,通常发生在两种情况下:1、当进程由于系统调用、中断或异常而进入核心态,从核心态返回用户态之前;2、当前进程在核心态中由睡眠刚被唤醒的时候,由于信号的存在而提前返回到用户空间中。示意图如下


    [进程信号量相关的数据描述]

    在进程数据结构task_struct中,与进程相关的数据有包括三个部分,如下所示
    long signal;
    struct sigaction sigaction[32];
    long blocked;         /* bitmap of masked signals */
    这里的sigaction数组就是我们前面所说的信号向量表,数组中的每个元素就相当于一个“信号向量”。它指明了当进程收到一个信号时所要做的处理。
    而struct sigaction的定义如下(在signal.h中)
    struct sigaction {
                     void (*sa_handler)(int );
                     sigset_t sa_mask;
                     int sa_flags;
                     void (*sa_restorer)(void );
    };
    其中sigset_t类型是有typedef定义而来,也在signal.h中定义,为  typedef unsigned int sigset_t;  /* 32 bits */
    Linux内核预先定义了两个信号处理函数
    #define SIG_DFL                 (( void (*)(int ))0)   /* default signal handling */
    #define SIG_IGN                  (( void (*)(int ))1)   /* ignore signal */
    SIG_DFL为默认的信号处理函数,SIG_IGN表示不对信号做任何处理。SIG_DFL的值为0,因此当信号向量表为空时,所有的信号都用SIG_DFL来处理。
    在sigaction结构体中,sa_handler为对应某个信号的信号处理函数。它可以为预先定义的两个值之一,或者是由用户自己定义的信号处理函数。sa_mask是信号处理的位图,sa_mask表示的32位二进制数中某一位为1时,表示当前位数的信号暂时被屏蔽,避免出现信号的嵌套处理,并且当前信号所对应的位图中的值必定为1。比如,当前正在处理信号向量表中第15个信号时,那么sa_mask&(1<<14)的结果肯定不为0。除非,sa_flags的值为SA_NOMASK。sa_flags用于控制对信号句柄的处理方式,它有三个可选的值,定义在signal.h头文件中
    #define SA_NOCLDSTOP 1
    #define SA_NOMASK       0x40000000
    #define SA_ONESHOT      0x80000000
    SA_NOCLDSTOP表示进程处于停止状态,不对信号做处理,SA_NOMASK表示不启用位图屏蔽信号,即这个时候可以运行信号嵌套。SA_ONESHOT指明信号处理函数一旦被调用过就恢复到默认的信号处理函数去,即使得sa_handler=SIG_DFL

    在进程中定义的与信号相关的数据还有long signal和long blocked。从数据的名字上看也容易猜出其具体用途。signal的二进制表示中的每一位表示一种信号,当它的二进制表示的某一位上的值为1时,表示收到了对应的信号。在内核中定义了22种信号。在signal.h文件中。具体的信号值的定义在后面说明使用的时候会给出。blocked指出进程在哪一位信号量上受到阻塞,blocked的二进制表示中的每一位被看成一个标识,当它的二进制表示中的某一位上的值为1时,表示进程在这一位对应的信号量上被阻塞,也就是说对应位上的信号暂时不用处理。

    [信号系统相关函数解析] 

         在这一部分中,对Linux系统的信号系统的函数进行解析。Linux内核的0.11版本中信号系统部分的函数不多,signal.c总共120行左右的代码,所以这里对所有在signal.c中的信号相关的函数进行解析
    int sys_sgetmask()  
    {
                     return current->blocked;
    }
    syst_sgetmark返回当前进程受阻塞的情况,current是一个的类型是struct task_struct*的全局变量,总是指向当前正在执行的进程。
    int sys_ssetmask(int newmask)
    {
                     int old=current->blocked;

                    current->blocked = newmask & ~(1<<(SIGKILL-1));
                     return old;
    }
    sys_ssetmask设置当前进程的阻塞掩码,同时返回进程旧的掩码值。SIGKILL定义在signal.h中,定义为#define SIGKILL 9。newmask&~(1<<SKILL-1)),操作可以使得结果的第8位(从第0位开始算起)为0,这个位对应的是强迫进程终止的信号.
    static inline void save_old( char * from,char * to)
    {
                     int i;

                    verify_area(to, sizeof(struct sigaction));    
                     for (i=0 ; i< sizeof (struct sigaction) ; i++) {
                                    put_fs_byte(*from,to);
                                    from++;
                                    to++;
                    }
    }
    在save_old函数中使用到了,verify_area和put_fs_byte两个函数,首先对这两个函数的作用进行说明。verify_area函数在fork.c中定义。它的原型是void verify_area(void * addr,int size)。对verify_area的具体定义涉及到对Linux内存管理方面的知识,这里不做详细解析,只需要了解verify_area的作用是对当前进程的地址addr到addr+size这一段进程空间以页为单位执行写操作前的检测。若页面是只读的,则执行共享检验和复制页面操作。puts_fs_byte函数的定义如下
    extern inline void put_fs_byte( char val,char *addr)
    {
    __asm__ ("movb %0,%%fs:%1":: "r" (val),"m" (*addr));
    }
    是一个按字节的拷贝函数,将var字符拷贝到addr指定的地址中去。那么,save_old函数的作用就是将由from指向的一个sigaction结构体拷贝到to指定的地方去,即保存一个信号的处理例程。
    static inline void get_new( char * from,char * to)
    {
                     int i;
                     for (i=0 ; i< sizeof ( struct sigaction) ; i++)
                                    *(to++) = get_fs_byte(from++);
    }
    将from指向的一个sigaction结构体拷贝到to指定的地方去。获取一个信号量的处理例程。get_fs_byte的定义与put_fs_byte类似。
    int sys_signal(int signum, long handler, long restorer)
    {
                     struct sigaction tmp;
      //Linux内核0.11版本中,限制一个进程能接受的最大信号量数是32个。信号量的编号是1到32。SIGKILL表示进程强制终止的信号量,是不允许直接对
     //进程设置强制终止的信号量的。
                     if (signum<1 || signum>32 || signum==SIGKILL)  
                                     return -1;
                    tmp.sa_handler = ( void (*)(int )) handler;
                    tmp.sa_mask = 0;  //sa_mask为0,表示不对任何一位上的信号量进行屏蔽
                    tmp.sa_flags = SA_ONESHOT | SA_NOMASK; //信号一旦被处理之后将恢复到默认的处理函数,并且不启动信号屏蔽
                    tmp.sa_restorer = ( void (*)(void )) restorer;   //恢复函数的设置
                    handler = ( long) current->sigaction[signum-1].sa_handler; //设置信号的处理函数
                    current->sigaction[signum-1] = tmp;  //设置当前进程的信号向量表
                     return handler;  
    }
    sys_signal函数设置当前进程某一个信号量的处理例程。有signum指定要设置的信号量,handler和restore分别指定信号的处理函数,和恢复函数。
    int sys_sigaction(int signum, const struct sigaction * action,
                     struct sigaction * oldaction)
    {
                     struct sigaction tmp;

                     if (signum<1 || signum>32 || signum==SIGKILL)   //同上一个函数的解释
                                     return -1;
                    tmp = current->sigaction[signum-1];   //获取旧的信号处理例程
                    get_new(( char *) action,
                                    ( char *) (signum-1+current->sigaction));    //保存新的信号处理例程
                     if (oldaction)                                                                //假如指定了旧的保存地址,就把就的信号处理例程保存起来
                                    save_old(( char *) &tmp,(char *) oldaction);
                     if (current->sigaction[signum-1].sa_flags & SA_NOMASK)    //如果在新的处理例程中,设置了不启用信号屏蔽,那么把sa_mask设置成0,不屏蔽
                                                                                            //何上的一位信号。否则就设置相应的屏蔽位。由此看来,除非显示第指定了不
                                                                                            //启用信号屏蔽表示,那么默认是要进行信号屏蔽的。不允许信号的嵌套处理。
                                    current->sigaction[signum-1].sa_mask = 0;             
                     else
                                    current->sigaction[signum-1].sa_mask |= (1<<(signum-1));
                     return 0;
    }
    sys_sigaction的作用也是对进程的某一信号量的处理例程进行设置。signum指定要设置的信号量,action指向新的信号处理例程,oldaction指向用于保存此信号量的旧的处理例程的地址。这个函数和syg_signal的作用其实相差不多,只不过这个是使用完全自定义的sigaction,而sys_signal只是设置了对应信号量的handler和restore,其余的使用默认设置。
    void do_signal(long signr,long eax, long ebx, long ecx, long edx,
                     long fs, long es, long ds,
                     long eip, long cs, long eflags,
                     unsigned long * esp, long ss)
    {
                     unsigned long sa_handler;
                     long old_eip=eip; 
                     struct sigaction * sa = current->sigaction + signr - 1; //根据信号量获取信号处理例程
                     int longs;
                     unsigned long * tmp_esp;

                    sa_handler = ( unsigned long ) sa->sa_handler;    //获取信号处理函数
                     if (sa_handler==1) //信号处理函数为1,即表示sa_handler==SIG_IGN,说明要忽略此信号,不做任何处理
                                     return;
                     if (!sa_handler) {     //sa_handler为0,即表示sa_handler!=SIG_DFL,说明要采用默认的信号处理动作,一般是退出进程的运行
                                     if (signr==SIGCHLD) //SIGCHLD定义在signal.h中,这个信号量表示子进程停止或者被终止。当子进程调用do_exit退出的时候,给其
                                                           //进程发送一个SIGCHILD的信号,表示自己停止运行了。
                                                     return;
                                     else                              //否则,调用默认的信号处理动作,退出进程
                                                    do_exit(1<<(signr-1));
                    }
                     if (sa->sa_flags & SA_ONESHOT)  //如果设置了SA_ONESHOT,那么信号处理函数调用之后,要把信号的处理函数设置成默认值,即设为0
                                    sa->sa_handler = NULL;
    //下面的这段代码用信号量句柄替换内核堆栈中原用户程序的eip,同时也将sa_resotre,signr,SA_NOMASK,eax,ecx,edx作为参数以及原调用系统
    //的程序返回指针及标志寄存器值压入堆栈。因此在本次调用中断返回用户程序时会首先执行用户的信号句柄程序,然后再继续执行用户程序。这样就
    //实现了信号处理函数的嵌入动作
                    *(&eip) = sa_handler;   //让EIP指向信号处理函数
                    longs = (sa->sa_flags & SA_NOMASK)?7:8;
                    *(&esp) -= longs;
                    verify_area(esp,longs*4);
                    tmp_esp=esp;
                    put_fs_long(( long) sa->sa_restorer,tmp_esp++);
                    put_fs_long(signr,tmp_esp++);
                     if (!(sa->sa_flags & SA_NOMASK))
                                    put_fs_long(current->blocked,tmp_esp++);
                    put_fs_long(eax,tmp_esp++);
                    put_fs_long(ecx,tmp_esp++);
                    put_fs_long(edx,tmp_esp++);
                    put_fs_long(eflags,tmp_esp++);
                    put_fs_long(old_eip,tmp_esp++);
                    current->blocked |= sa->sa_mask;   //插入完成后,设置进程在对应上的信号阻塞情况
    }
    下图画出了,插入之后的堆栈的示意图,设置了SA_NOMASK的情况。put_fs_long是向指定的地址写入一个4字节大小的数据,它的函数原型是
    void put_fs_long(unsigned long val, unsigned long * addr),把val写到由addr指定的地址中去

     do_signal是具体的信号处理函数,根据当前进程的信号状态,做出相应的操作.

    [进程信号使用的具体实例] 
    这一部分解析一些进程之间使用信号量的具体实例
    1、首先是信号量相关的初始化
    在进程调用do_execv启动一个新的程序时,会设置进程信号量的初始值,是将信号向量表的每一项设为NULL
    for (i=0 ; i<32 ; i++)
         current->sigaction[i].sa_handler = NULL;
    而前面提到过,创建一个新进程的时候,会把这个进程的signal设置0.
    2、进程退出时,即进程调用了exit的系统调用
    do_exit函数中有如下部分语句
    for (i=0 ; i<NR_TASKS ; i++)
                                     if (task[i] && task[i]->father == current->pid) {
                                                    task[i]->father = 1;
                                                     if (task[i]->state == TASK_ZOMBIE)
                                                                     /* assumption task[1] is always init */
                                                                    ( void) send_sig(SIGCHLD, task[1], 1);
                                    }
         这段代码作用是先找到当前要退出的进程的所有子进程,将这些进程的父进程设为进程1(一个内核常驻进程)。然后检查,这些子进程中,是否有进程状态为僵死状态的,如果有,就向其父进程(也就是进程1)发送一个子进程已僵死的信号。等待父进程的处理。
         在do_exit函数体的后面一点部分,有如下语句
    if (current->leader)
           kill_session();
    检查当前进程是否为其所在进程组的组长进程,如果是的,就结束会话。而kill_session函数的定义如下(在exit.c文件中)
    static void kill_session(void)
    {
                     struct task_struct **p = NR_TASKS + task;
                    
                     while (--p > &FIRST_TASK) {
                                     if (*p && (*p)->session == current->session)
                                                    (*p)->signal |= 1<<(SIGHUP-1);
                    }
    }
    kill_session所做的事情,就是检查所有与当前进程在同一个会话组里面的进程,给这些进程发送一个SIGHUP信号,即会话已经结束,进程Hang起
    在进程状态设置之后,需要通知这个进程的父进程,告知其一个子进程终止。于是有如下代码
    current->state = TASK_ZOMBIE;
    current->exit_code = code;
    tell_father(current->father);
    对tell_father的定义如下
    static void tell_father(int pid)
    {
                     int i;

                     if (pid)
                                     for (i=0;i<NR_TASKS;i++) {
                                                     if (!task[i])
                                                                     continue;
                                                     if (task[i]->pid != pid)
                                                                     continue;
                                                    task[i]->signal |= (1<<(SIGCHLD-1)); //找到父进程,设置父进程的信号量
                                                     return;
                                    }
    /* if we don't find any fathers, we just release ourselves */
    /* This is not really OK. Must change it to make father 1 */
                    printk( "BAD BAD - no father found\n\r" );
                    release(current);
    }
     tell_father的作用就是,给其父进程发信号,告诉子进程已经终止。如果没找到父进程,就将自己释放
    3、进程调度时的信号处理
    在进程调度函数中,会检查进程的时钟信号
    for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
                                     if (*p) {
                                                     if ((*p)->alarm && (*p)->alarm < jiffies) {
                                                                                    (*p)->signal |= (1<<(SIGALRM-1));
                                                                                    (*p)->alarm = 0;
                                                                    }
                                                     if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) && 
                                                    (*p)->state==TASK_INTERRUPTIBLE)
                                                                    (*p)->state=TASK_RUNNING;
                                    }
    这段代码是刚进入schedule函数时首先执行的。先检查进程是否收到了时钟信号,如果收到就做设置信号量。然后在下面部分检查进程是否获得了所需的信号,并且是否可以现在处理这个信号,如果是,就将进程状态设置为运行。

    PS:还有更多使用信号的实例,有机会再写!
    展开全文
  • 城市轨道交通信号系统是用于对列车
  • 城市轨道交通信号系统

    千次阅读 2008-05-13 21:43:00
    城市轨道交通信号系统是保证列车运行安全,实现行车指挥和列车运行现代化,提高运输效率的关键系统设备。城市轨道交通信号系统通常由列车自动控制系统(Automatic Train Control,简称ATC)组成,ATC系统包括三个子...
  • 中国高速铁路信号系统发展与思考

    千次阅读 2012-12-10 17:36:41
    一、铁路信号系统  铁路信号系统是为了保证运输安全而诞生和发展的,它的第一使命是保证行车安全,没有铁路信号,就没有铁路运输的安全。由铁路信号构成的信息与控制系统、铁路固定设备(线路、桥、隧)和移动设备...
  • 系统的分类 根据不同的角度,可以把系统分成不同的种类: 连续系统和离散系统 即时系统与动态系统 集总参数系统和分布参数系统 可逆系统与不可逆系统 线性系统 时不变系统 因果系统 稳定系统 系统跳过了电路的具体...
  • 信号系统一些基本概念

    千次阅读 2018-01-27 10:28:15
    若不是整周期截取数据,则截断将使信号波形两端产生突变,所截取的一段信号与原信号有很大不同,对这个被截断的时域信号进行谱分析时,本来集中的线谱将分散在该线谱临近的频带内,产生原信号中不存在的新的频率成分...
  • 信号系统中的特征函数和特征值

    千次阅读 2020-06-07 20:55:07
    一个信号,若系统对该信号的输出响应仅是一个常数(可能是复数)乘以输入,则称该信号系统的**特征函数**,而幅度因子称为系统的**特征值**。
  • 本科期间信号系统中学习到了卷积概念, 卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列x(n)和h(n),则卷积的结果 其中星号*表示卷积。当时序n=0时,序列h(-i)是h(i)的时序i取反的结果;...
  • 在电影《偷天换日》(The Italian Job)里有个情景, 莱尔通过入侵洛杉矶的交通信号系统, 控制红绿灯,来迫使运送金块的车在预定地点停车。 在最近的USENIX Security 2014上, 密歇根大学的一个研究团队发布了一份...
  • 信号系统与数字信号处理一点点心得

    千次阅读 多人点赞 2013-06-22 16:00:31
    为什么要讲线性时不变系统 为什么h(t)就能表征一个系统 什么是因果系统跟h(t)有什么联系,为什么有联系 什么是稳定系统跟h(t)有什么联系,为什么有联系 什么是滤波器 拉普拉斯变换又是怎么回事 拉普拉是...
  • 数字电视信号系统架构

    千次阅读 2012-10-30 13:37:40
    信号由天线或者cable进入高频头,混频成中频,分两路进入数字与模拟demod,模拟电视直接进模拟dec模块,除此之外还有av yuv vga hdmi等从信号源产生的信号也是直接进入模拟dec解码后,送入视频后处理vpn模块处理,...
  • f:表示输入信号的函数。 sys:表示系统的微分方程。 获取系统的微分方程tf sys=tf(b,a) b:微分方程等号右端的系数向量。 a:表示微分方程等号左边的系数向量。 例子: sys=tf([1],[1,2,77]);%tf函数获得系统...
  • 信号系统与卷积

    千次阅读 热门讨论 2009-06-15 21:02:00
    由于其在数学、物理学、电子工程、信号处理、计算机科学中极为重要,所以我试图在本文中讲解卷积的概念,力求易读易懂,让尽可能多的人理解卷积。 前几天见到VC知识库论坛上有人提问:“卷积是什么意思?”,似乎...
  • 目录第二章 信号系统2.1 什么是信号信号如何表征2.1.1信号的概念2.1.1信号的表征方法2.2 信号如何分类2.2.1 信号类别及基本概念2.2.2 确定信号与随机信号2.2.3 连续时间信号与离散时间信号2.3 常见信号2.4 特殊...
  • 信号系统】复习总结笔记

    千次阅读 多人点赞 2016-12-18 15:05:00
    学习笔记(信号系统) 来源:网络 第一章 信号系统 信号的概念、描述和分类 信号的基本运算 典型信号 系统的概念和分类 1、常常把来自外界的各种报道统称为消息; 信息是消息中有意义的内容;...
  • 信号系统
  • 信号系统

    千次阅读 2018-10-30 21:33:51
    1. 连续时间和离散时间信号 1.1. 连续时间和离散时间信号的定义 连续时间信号的自变量是连续可变的,信号在自变量的连续值上都有定义;而离散时间信号的自变量仅仅定义在离散时刻点上,也就是自变量仅取在一组离散值...
  • 按信号的传递方式分类 连续系统  系统中各部分的信号都是连续的模拟信号。连续系统的运动特性用微分方程来描述。 离散系统 ... 经典的控制理论是基于连续信号系统的。  系统信息由连续信号来表示
  • 全方面的了解超宽带信号高速采集记录回放系统

    万次阅读 多人点赞 2019-01-07 09:25:47
    超宽带信号高速采集记录存储回放系统主要用于对超宽带信号进行长时间高速连续实时采集记录和回放产生,适用于雷达、无线通信、软件无线电、电子对抗、电子侦察、卫星导航、复杂电磁环境模拟信号的高速采集、分析、...
  • 奥本海姆信号系统

    千次阅读 2019-06-28 23:21:01
    奥本海姆<信号系统>
  • linux系统编程之信号(五):实时信号与sigqueue函数

    千次阅读 多人点赞 2013-05-19 13:04:02
    功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。 原型:int sigqueue(pid_t pid, int sig, const union sigval value); 参数:  sigqueue的第一个参数是指定...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 78,966
精华内容 31,586
关键字:

信号系统