精华内容
下载资源
问答
  • 为了提高通信信号的稳定采集性能,提出一种改进的大数据环境下无线终端...测试结果表明,该信号采集系统能实现大数据环境下的无线终端智能通信信号采集,输出信号的信噪比较高,误比特率较低,具有很好的抗干扰性能。
  • 终端控制与信号浅析

    2015-04-27 18:51:40
    终端控制程序在终端显示时会与程序本身有一些出入,比如在运行下面这段代码时运行时直接按回车,则两次的输出结果都是10,即\n的ASCII码。在printf输出\n时,终端显示\r\n,在getchar读入的时候ENTER,又被处理成\n...

    终端控制

    程序在终端显示时会与程序本身有一些出入,比如在运行下面这段代码时运行时直接按回车,则两次的输出结果都是10,即\n的ASCII码。在printf输出\n时,终端显示\r\n,在getchar读入的时候ENTER,又被处理成\n。又比如我们都知道程序的I/O有缓冲区,能够暂存程序输入输出的信息等特点。

    #include "stdio.h"
    
    int main(int argc, char const *argv[])
    {
         char ch;
         ch = '\n';
         printf("%d\n", ch);
         ch = getchar();
         printf("%d\n", ch);
         return 0;
    }

    这些东西都与本章的一个重点设备驱动器有关,当我们打开一个终端时,终端驱动器就调用了默认的设置,规范处理终端与程序之间的数据流,比如缓冲、编辑等功能。默认的顺序是:1、控制字符处理,2、回显,3、将”\r”转换成”\n”,4、输入编辑程序。规范处理也能够通过改变属性等变为非规范处理:如stty -icanon可关闭规范处理,stty -echo可关闭回显。通过调试设备驱动器的属性能够使程序的人机交互更人性化。

    信号
    运行一个进程时,ctrl_c能发出SIGINT信号中断程序,ctrl_d能发出SIGQUIT信号退出程序。然而实际上进程处理信号可以有三种属性可以条件:1、接收默认处理2、忽略信号3、调用一个函数(signal函数)。
    result = singnal(int signum, void(*action)(int));
    action可以是任意函数也可以是SIG_IGN(忽略信号)和SIG_DFL(将信号恢复为默认处理)两个特殊值。

    异步信号与按键都属于键盘输入。默认状态下,常规的键盘输入将数据通过驱动程序传输到程序,而有些键则会调用驱动程序中的编辑函数,如按下退格键时,驱动程序将前一字符从行缓存中删除,并将命令发送到终端,使之从显示器中删除程序。而信号则是调用内核中的某个函数,给进程发送一个信号。

    展开全文
  • 一个pan ID代表一个网络,在此网络里只能一个协调器,多个路由器和多个终端设备, 而且它们还需要使用同一通道来通信. 在相同的户内环境里,如需要多个zigbee网络来通信的话,必须修改工程里的pan ID和通道的...

    在zigbee网络里pan ID非常非常重要. 一个pan ID代表一个网络,在此网络里只能一个协调器,多个路由器和多个终端设备, 而且它们还需要使用同一通道来通信.



    在相同的户内环境里,如需要多个zigbee网络来通信的话,必须修改工程里的pan ID和通道的设置:

    这里写图片描述

    -DDEFAULT_CHANLIST=0x00000800  //就是表示使用通道, 不同的通道表示不同的频段从(2405 – 2480)MHz
    
    -DZDAPP_CONFIG_PAN_ID=0xFFFF //就是pan ID的配置了。 一定要注意不能有多个同用此id的协调器


    设置功率输出,加大传输距离:
    这里写图片描述
    // 设置HAL_PA_LNA 表示使用信号放大功能


    //修改输出信号强度, 修改图中的文件里的内容, 结果如下:
    这里写图片描述
    这里写图片描述

    //关于寄存器OBSSEL0,OBSSEL1的配置说明:
    这里写图片描述


    这里写图片描述

    //原值为19dB, 改为20dB.

    展开全文
  • QT QProcess执行终端命令并实时输出回显

    万次阅读 多人点赞 2018-11-16 22:38:21
    在QT程序中我们经常需要与其他的程序间进行交互,而与终端进行交互就是一个例子。在不需要获取返回信息的情况下我们可以直接使用"system()"函数执行,但是当需要获取执行的结果或者需要实时地将结果输出到...
    • 引子

    在QT程序中我们经常需要与其他的程序间进行交互,而与终端进行交互就是一个例子。在不需要获取返回信息的情况下我们可以直接使用"system()"函数执行,但是当需要获取执行的结果或者需要实时地将结果输出到窗口上时,就比较难办了,需要涉及进程管道等等。而QT提供的QProcess类则大大简化了这一过程。

    QProcess是QT提供的与外部程序进行交互的一个类,主要使用到以下的函数:

    start();                     //启动一个进程
    kill();                      //关闭启动的外部进程
    write();                     //向外部进程写入数据
    readAllStandardOutput();     //读取外部进程的标准输出
    readAllStandardError();      //读取外部进程的错误信息
    • 创建QProcess对象并连接信号与槽
    cmd = new QProcess(this);
    connect(cmd , SIGNAL(readyReadStandardOutput()) , this , SLOT(on_readoutput()));
    connect(cmd , SIGNAL(readyReadStandardError()) , this , SLOT(on_readerror()));
    • 实现槽函数

    接收到标准输出:

    void MainWindow::on_readoutput()
    {
        ui->textEdit->append(cmd->readAllStandardOutput().data());   //将输出信息读取到编辑框
    }

    接收到错误信息:

    void MainWindow::on_readerror()
    {
        QMessageBox::information(0, "Error", cmd->readAllStandardError().data());    //弹出信息框提示错误信息
    }
    • 启动外部程序并写入数据
    cmd->start("bash");             //启动终端(Windows下改为cmd)
    cmd->waitForStarted();        //等待启动完成
    cmd->write("ls\n");               //向终端写入“ls”命令,注意尾部的“\n”不可省略

    没有意外的话在编辑框中将看见输出了当前目录下的文件:

    同理,可以执行绝大部分在终端中执行的命令,不过有些程序所需要的实现可能不太一样,比如更新软件包,则需执行如下命令:

    sudo -S apt-get update

    如果不带参数"-S",则会返回错误信息:“sudo:没有终端存在,且未指定askpass程序”

     

    因此此种方法启动程序的时候如果需要root权限,则需要在"sudo"后加上选项"-S"。

    还有的情况就是因为终端启动的时候其实已经帮我们读取了很多环境变量,但是我们在QT程序中直接启动bash的时候这些环境变量尚未被读取,导致一些程序无法启动,报错“未找到命令”。这时需要我们主动去source一遍对应的环境。

    • 善后

    QProcess启动的外部程序并不会随着QT程序的关闭而关闭,所以在窗口的销毁函数中加入以下代码,使得窗口销毁时连带终结外部进程。

    if(cmd)
    {
          cmd->close();
          cmd->waitForFinished();
    }
    • 写在最后

    代码只是关键部分的代码,还有头文件中的声明、槽函数的声明等等一些琐碎细节的地方没有写出在文中,还请自行添加。同时为了方便你们参照,我也将工程上传了一份到GitHub中,如有不懂之处,可参照我的GitHub上的代码:QProcess_Examples-字节莫的GitHub

    如有问题欢迎留言讨论。

    欢迎关注字节莫的微信公众号,探讨更多技术、人文的思考,一起进步!

    本文首发于「字节莫的个人博客」,欢迎前往交流!

    原文链接:https://blog.str-mo.com/tech/153/

    展开全文
  • APUE 上的定义如下: 守护进程也称 daemon 进程,是生存期较长的一种进程,它们常常在系统自举时启动,仅在系统关闭时才终止。因为它们没有控制终端,所以说它们是再后台运行的。
    APUE 上的定义如下: 守护进程也称  daemon 进程,是生存期较长的一种进程,它们常常在系统自举时启动,仅在系统关闭时才终止。因为它们没有控制终端,所以说它们是再后台运行的。  
    Daemon 功能实现】

          首先,讲解下 daemon 实现的基本原则。事实上,编写守护进程程序时是存在一些基本规则的,目的是防止产生不需要的交互作用(比如与终端的交互)。规则如下:

    1. 调用 umask 将文件模式创建屏蔽字设置为 0 原因防止继承得来的文件模式创建屏蔽字会拒绝设置某些权限的情况。
    2. 调用 fork ,然后使父进程退出(exit)。原因第一,令启动 daemon 进程的 shell 认为命令已经执行完毕;第二,令产生的子进程不是其所在进程组的组长。
    3. 调用 setsid 以创建一个新会话。原因使调用进程,第一,成为新会话的首进程;第二,成为新进程组的组长进程;第三,没有控制终端(在基于 System V 的系统中可以通过 fork 两次来达到防止取得控制终端的效果的,其不再需要下面的规则6)。
    4. 将当前工作目录更改为根目录。原因防止出现不能 umount 的问题。
    5. 关闭不再需要的文件描述符。原因令守护进程不再持有从父进程继承来的某些文件描述符。
    6. 某些守护进程打 /dev/null 使其具有文件描述符012原因防止守护进程与终端设备相关联。

     

    有了上面的原则,现在对照下 MySQL Proxy 中的代码: 

    /**
     * start the app in the background 
     * 
     * UNIX-version
     */
    void chassis_unix_daemonize(void) {
    #ifdef _WIN32
    	g_assert_not_reached(); /* shouldn't be tried to be called on win32 */
    #else
    #ifdef SIGTTOU
    	signal(SIGTTOU, SIG_IGN);
    #endif
    #ifdef SIGTTIN
    	signal(SIGTTIN, SIG_IGN);
    #endif
    #ifdef SIGTSTP
    	signal(SIGTSTP, SIG_IGN);
    #endif
    	if (fork() != 0) exit(0);
    	
    	if (setsid() == -1) exit(0);
    
    	signal(SIGHUP, SIG_IGN);
    
    	if (fork() != 0) exit(0);
    	
    	chdir("/");
    	
    	umask(0);
    #endif
    }


    从上面的实现代码中,可以看出以下几点:

    • 代码执行的先后顺序有的是必须的(如setsid 之前的 fork),有的不是必须的(如 umask 放在最后执行)。
    • 实现中使用了两次 fork ,为 System V 中理念。
    • 在 setsid 和第二次 fork 之间插入了 signal 处理,用于对 SIGHUP 执行 SIG_IGN 处理。

          在上述  daemon 编程规则中没有提到 signal 处理的问,那么针对 SIGHUP 的处理代表的是什么意思呢?还是参阅 APUE

          如果终端接口检测到一个连接断开,则将此信号发送给与该终端相关的控制进程(会话首进程)。仅当终端的 CLOCAL 标志没有设置时,上述条件下才产生此信号。

          有别于由终端正常产生的信号(如中断、退出和挂起)-- 这些信号总是传递给前台进程组 --  SIGHUP 信号可以发送到位于后台运行的会话首进程。SIGHUP 信号的默认处理动作是终止当前进程。通常会使用该信号来通知守护进程,以重新读取它们的配置文件,因为守护进程不会有控制终端,而且通常决不会收到这种信号。

          从上面这段文字可以看出,这里增加了 signal 信号处理的原因是,在 setsid 和第二次 fork 之间,当前的子进程仍旧是会话首进程,有可能会在收到 SIGHUP 信号时终止,所以这里通过设置  SIG_IGN 进行忽略。

    至此,一个 daemon-mode 的守护进程就启动了。

     

    在linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程,都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。 

        daemon进程是后台守护进程,有时候也叫精灵进程(agent).linux 下server都是daemon进程。相信大部分开发人员都知道如何去写一个daemon进程。但是另一方面,大部分人不知道为什么要这么做,不少人是从某个地方copy一个函数,拿来主义。但是具体为什么这么实现,却不是很透彻。


      见过一些面试官或被面试人。很多人解释daemon进程存在的理由是因为僵死进程。或者输入输出。其实和这些东西一毛钱关系都没有。 daemon函数存在的原因是因为控制终端由于某些原因(如断开终端链接)会发送一些信号的原因。而接收进城处理这些信号缺省动作会让进程退出。这些信号会由于终端上敲一些特殊按键而产生。

      贴一个daemon函数常见的实现:
    1. int daemon(void)
    2. {
    3.     pid_t pid = fork();

    4.     if( pid != 0 ) exit(0);//parent

    5.     //first children
    6.     if(setsid() == -1)
    7.     {
    8.        printf("setsid failed\n");
    9.        assert(0);
    10.        exit(-1);
    11.     }

    12.     umask(0);


    13.     pid = fork();

    14.     if( pid !=  0) exit(0);
    15.   
    16.     //second children  
    17.     chdir ("/");

    18.     for (int i = 0; i < 3; i++)
    19.     {
    20.         close (i);
    21.     }


    22.     int stdfd = open ("/dev/null", O_RDWR);
    23.     dup2(stdfd, STDOUT_FILENO);
    24.     dup2(stdfd, STDERR_FILENO);

    25.     return 0;
    26. }
        1 、第一次fork的作用是让shell 认为本条命令 已经终止,不用挂在终端输入上。还有一个作用是为后面setsid服务。setsid的调用者不能是进程组组长(group leader). 此时父进程是进程组组长。
        
        2 、setsid() 是本函数最重要的一个调用。它完成了daemon函数想要做的大部分事情。调用完整个函数。子进程是会话组长(sid==pid),也是进程组组长(pgid == pid),并且脱离了原来控制终端。到了这一步,基本上不管控制终端如何怎么样。新的进程都不会收到那些信号。

        3  、经过前面2个步骤,基本想要做的都做了。第2次fork不是必须的。也看到很多开源服务没有fork第二次。fork第二次主要目的是。防止进程再次打开一个控制终端。 因为打开一个控制终端的前台条件是该进程必须是会话组长。再fork一次,子进程ID != sid(sid是进程父进程的sid)。所以也无法打开新的控制终端。

        daemon目的就是防止终端产生的一些信号让进程退出。上面函数并没有直接调用signal函数去处理它。而是间接通过fork和setsid函数使用更少代码优雅处理。而被有些人误以为是僵死进程的原因需要这样处理。

        当然,也有很多程序不是像上面函数那样去实现。而是直接通过忽略信号方式处理。这样其实也不错,因为这些信号很少会有用到的价值。直接忽略基本上不存在误杀的情况。反正达到最终目的就可以。条条大路通罗马。

       下面罗列一下控制终端会产生哪些信号。程序中只要处理好这些信号,同样能达到上面函数实现的目的。

        //后台进程读取/写入终端输入产生下面两个信号,或者控制终端不存在情况读取和写入会产生
       signal(SIGTTOU, SIG_IGN);
       signal(SIGTTIN, SIG_IGN);

       //按CTRL-C ,CTRL-\ CTRL-Z会向前台进程组发送下面这些信号
       signal(SIGINT,  SIG_IGN );
       signal(SIGQUIT, SIG_IGN );
       signal(SIGTSTP, SIG_IGN );
       
        //终端断开,会给会话组长或孤儿进程组所有成员发送下面信号
       signal(SIGHUP,  SIG_IGN );

       还有有些信号也可以由终端shell产生,需要关注
       signal(SIGCONT, SIG_IGN );
       signal(SIGSTOP, SIG_IGN );


      上面这些信号 ,应该有些程序缺省处理(SIG_DFL)本身动作就是忽略(SIG_IGN),不是退出进程。不过按照上面写也不会造成什么问题。

        在编写精灵进程程序时需要遵循一些基本规则,以便防止产生并不希望的交互作用。下面先说明这些规则,然后是一个按照规则编写的函数daemon_init。

        

        1.  首先做的是调用fork,然后使父进程exit。这样做实现了下面几点:

        第一:如果该精灵进程是由一条简单shell命令启动的,那么使父进程终止使得shell认为这条命令已经执行完成;(之后的所有工作都在子进程中完成,而用户在Shell终端里则可以执行其他命令,从而在形式上做到了与控制终端的脱离。)

        第二:在Linux中父进程先于子进程退出会造成子进程成为孤儿进程,而每当系统发现一个孤儿进程,就会自动由1号进程(init)收养它,这样,原先的子进程就会变成init的子进程;

        第三:子进程继承了父进程的进程组ID,但具有一个新的进程ID,这就保证了子进程不是一个进程组的首进程。这对于下面就要做的setsid调用是必要的前提条件

       

        2.  调用setsid以创建一个新对话期。于是执行9.5节中列举的三个操作,使调用进程:

        第一:成为新对话期的首进程;

        第二:成为一个新进程组的首进程;

        第三:没有控制终端。

        在SVR之下,有些人建议在此时再调用fork,并使父进程终止。第二个子进程作为精灵进程继续运行。这样就保证了该精灵进程不是对话期的首进程,于是按照SVR规则(见9.6节)可以防止它取得控制终端。另一方面,为了避免取得控制终端,无论何时打开一个终端设备都要指定O_NOCTTY

     

        3.  将当前工作目录更改为根目录。父进程继承过来的当前工作目录可能在一个装配的文件系统中。因为精灵进程通常在系统再引导之前是一直存在的,所以如果精灵进程的当前工作目录在一个装配文件系统中,那么该文件系统就不能被拆卸。

        另外,某些精灵进程可能会把当前工作目录更改到某个指定位置,在此位置做它们的工作。

        例如,行式打印机假脱机精灵进程常常将其工作目录更改到它们的spool目录上。

     

        4.  将文件方式创建屏蔽字设置为0。由继承得来的文件方式创建屏蔽字可能会拒绝设置某些许可权。例如,若精灵进程要创建一个组可读、写的文件,而继承的文件方式创建屏蔽字,屏蔽了这两种许可权,则要求的组可读、写就不能起作用。

     

        5.  关闭不在需要的文件描述符。这样使精灵进程就不再持有从其父进程继承来的某些文件描述符(父进程可能是shell进程,或某个其他进程)。但是,究竟关闭那些描述符则与具体的精灵进程有关,所以在下面的例子中不包含此步骤。可以使用程序2-3中的open_max函数来决定最高文件描述符值,并关闭直到该值的所有描述符。

     

     

     
     

    daemon进程原理及实现(来源于网络,后整理)  

    为何两次Fork

    这是创建Daemon进程的大致步骤及作用:

    • 第一次fork(产生父子进程,父进程退出,子进程与父进程控制终端脱离)
    • 子进程setsid(子进程成为会话组长,与父进程会话脱离)
    • 第二次fork(产生子孙进程,子进程退出,孙进程成为Daemon最终进程)
    • 切换工作目录、设置文件创建掩模、关闭所有打开文件句柄等

    原则上来说在第一次fork后,子进程即与父进程的控制终端脱离关系,父进程退出后,子进程被init接管,基本达到了Daemon进程要求。但还差了一点,子进程与父进程还在同一个会话组,因此子进程需要调用setsid以达到与父进程会话脱离。也就是这个setsid,使子进程成为了新的会话组组长,却导致了新的问题产生:在Linux中会话组长可以重新申请打开一个控制终端。为了彻底与控制终端断绝关系,我们需要一个非会话组长的进程,子进程的子进程正是我们要的。

     

     

     

     

            守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程是一种很有用的进 程。Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。 比如,作业规划进程crond,打印进程lpd等。

            守护进程的编程本身并不复杂,复杂的是各种版本的Unix的实现机制不尽相同,造成不同 Unix环境下守护进程的编程规则并不一致。需要注意,照搬某些书上的规则(特别是BSD4.3和低版本的System V)到Linux会出现错误的。下面将给出Linux下守护进程的编程要点和详细实例。

    一. 守护进程及其特性

            守护进程最重要的特性是后台运行。在这一点上DOS下的常驻内存程序TSR与之相似。其次,守护进程必须与其运行前的环境隔离开来。这些环 境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下 来的。最后,守护进程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端(通常是 shell)执行。

            总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。如果对进程有比较深入的认识就更容易理解和编程了。

    二. 守护进程的编程要点

            不同Unix环境下守护进程的编程规则并不一致。所幸的是守护进程的编程原则其实都一样,区别在于具体的实现细节不同。这个原则 就是要满足守护进程的特性。同时,Linux是基于Syetem V的SVR4并遵循Posix标准,实现起来与BSD4相比更方便。编程要点如下;

    1. 在后台运行。

            为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。

        if(pid=fork())

    exit(0); //是父进程,结束父进程,子进程继续

    2. 脱离控制终端,登录会话和进程组

            有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。 控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长:

        setsid(); //设置为会话组长

            说明:当进程是会话组长时setsid()调用失败。但第一点(fork())已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。

    3. 禁止进程重新打开控制终端

            现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端(再fork一次):

    if(pid=fork()) 

        exit(0); //结束第一子进程,第二子进程继续(第二子进程不再是会话组长)

    4. 关闭打开的文件描述符

            进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,可能会造成进程所占用的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们:

    for(i=0;i < 3; ++i)

    close(i); //0, 1, 2 分别表示标准输入、标准输出和标准错误

          当然,此处关闭哪个文件描述符与实际需要相关,也可以关闭以后再重新打开。

    5. 改变当前工作目录

            进程活动时,如果该目录是一个挂载的目录,将导致其文件系统不能卸载。一般需要将工作目录改变到根目录(chdir("/"))。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如 /tmp

    6. 重设文件创建掩模

            进程从创建它的父进程那里继承了文件创建掩模。由继承得来的文件方式创建屏蔽字可能会拒绝设置某些许可权。例如,若daemon进程要创建一个组可读、写的文件,而继承的文件方式创建屏蔽字,屏蔽了这两种许可权,则要求的组可读、写就不能起作用。为防止这一点,将文件创建掩模清除:

    umask(0);

    7. 处理SIGCHLD信号

            处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结 束,子进程将成为僵尸进程(zombie)。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下 可以简单地将 SIGCHLD信号的操作设为SIG_IGN。

    signal(SIGCHLD,SIG_IGN);

            这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。

    三. 守护进程实例

            fork()两次,将孙子进程“过继”给1号进程init,如果孙子进程成功,其父进程将会是系统1号进程init,如果失败,将由init负责收拾残局。

    void InitAsDaemon()

    {

    if (fork() > 0 ) exit(0);

    setsid();

    signal(SIGINT, SIG_IGN);

    signal(SIGHUPSIG_IGN);

    signal(SIGQUIT, SIG_IGN);

    signal(SIGPIPE, SIG_IGN);

    signal(SIGTOU, SIG_IGN);

    signal(SIGTIN, SIG_IGN);

    signal(SIGCHLD, SIG_IGN);

    if (fork() > 0) exit(0);

    chdir("/");

    umusk(0);

    }

    四. wait和waitpid

            两者相同点都是用于在创建子进程之后,阻塞自己,然后检查自己的子进程中是否有僵尸进程存在,如果存在,该父进程就释放僵尸进程占用的资源,并返回,如果没有这样的僵尸进程,就一直阻塞。

            不同点是后者还有两个pid和option参数。

            pid:当pid > 0时,只等待进程号为pid的进程退出;pid == -1时,等待任意子进程,作用等同于wait;pid == 0时,等待同一进程组中任意子进程;pid < -1 时,等待某个进程组的任意进程,该进程组的组号为pid的绝对值。

            option:有两个值,WNOHANG和WUNTRACED,前者使得waitpid立即返回而不管有没有子进程退出;后者是指其子进程集合中,如果有子进程是STOPED状态,就立即返回,如果该进程是被traced的,那么即使不提供WUNTRACED参数,也立即返回。

           于是可以看出,wait是等待第一个退出的子进程,而waitpid是等待指定子进程退出。因此对于多进程服务器,使用waitpid可以避免因为第一个子进程退出调用了wait,而造成剩余子进程没有wait来处理,引起的僵尸进程的问题。

    五. 僵尸进程的处理

            僵尸进程是无法使用kill或者killall来杀死的,虽然僵尸进程并不占用很多系统资源(只是占用进程表process table中的一个项),但是过多的僵尸进程还是会对系统性能造成影响(达到系统进程数上限),因此应尽可能避免:

            1、改写父进程:如上所述,fork两次,将init作为其父进程,由系统负责清理

            2、kill掉僵尸进程的父进程,交由系统处理。

            使用

            ps auwx可以查看系统中僵尸进程,僵尸进程的状态会被标注为“Z”。或者

            ps axf   以树形展示进程表

            ps axm    列出线程,linux下进程线程一致

            ps aux   列出进程的详细信息

     

    展开全文
  •  高频信号传输时,信号波长相对传输线较短,信号在传输线终端会形成反射波,干扰原信号,所以需要在传输线末端加终端电阻,使信号到达传输线末端后不反射。对于低频信号则不用。在长线信号传输时,一般为了避免信号...
  • Linux终端输入输出(termios)函数

    千次阅读 2012-09-22 21:33:57
    termios系列函数-tcgetattr, tcsetattr, tcsendbreak, tcdrain, tcflush, tcflow, cfmakeraw, cfgetospeed, cfgetispeed, cfsetispeed, cfsetospeed, cfsetspeed等,用以获取/设置终端设备的属性/控制/速度。...
  • CC2530显示终端信号强度 RSSI LQI

    千次阅读 2016-04-17 02:14:52
    项目情况:低功耗型无线温湿度监控...因为要了解设备的运行状态,所以要监控探头的电池电压和信号强度情况。 获取方法,建立一个全局变量:uint8 zclSampleLightRssi; 然后跑到mac_rx.c,找到static void rxStartI
  • 我们已经拆解了天线是如何发送和接收空中的高频无线电磁波信号、拆解了无线终端如何对射频前端的高频电信号进行进一步处理的、还拆解了无线终端的发送和接收如何分时复用天线的半双工模式。 我们还拆解无线终端是...
  • 信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。 信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。...
  • 几乎所有的开发板都会支持串口输出调试,但不是每次我们都有那么好运能直接看到串口输出。...另外有可能是输出电压不够,因为开发板输出的串口信号电压一般比较低,如果开发板本身没有增强输出模块,则需要自己接
  • 本篇将进一步拆解无线终端是如何对射频电信号进行进一步的处理,包括发送方向的功率放大器和接收方向的低噪声放大器。 为什么需要射频信号放大器呢? 从发送方向来看:功率放大器使得射频芯片产生的低功率的高频率...
  • 四、在终端窗口中Qt编程信号的应用实例 打开一个终端,用vi建立一个文件t2.c,键入如下程序: #include #include int main( int argc, char **argv ) { QApplication a( argc, argv ); //创建QApplic
  • 信号

    千次阅读 2018-01-22 18:23:41
    1、概念  提及信号我们首先想到的是什么?有人想到赛场上裁判的信号枪,有人想到路口的红绿灯……;信号在我们生活中随处可见。在计算机中,信号是信息的载体,... 例如:A给B发送信号,B收到信号之前执行自己的代
  • 有些视频应用中,信号输出RGB信号以及复合同步信号...例如,考虑到具有75Ω终端电阻的视频信号源具有0.7VP-P的绿色信号输入和0.3V的复合同步信号,图1中,MAX95*后的绿色通道输出信号为1VP-P。对于信号源产生的0.7VP
  • 终端、虚拟终端和伪终端

    千次阅读 2011-11-25 17:24:48
    按照Lions的说法,远古时候存在各种串行设备,它们的物理接口与传输特性各自有异,而它们作为终端有一些代码可以抽象出来,于是形成了最早的tty层。 Unix V6的tty实现十分简洁,在Lions提供的册子里才占两三...
  • 终端接口

    千次阅读 2016-06-10 20:40:51
    POSIX终端接口 ? 很多系统都支持POSIX终端(串口)接口。程序可以利用这个接口来改变终端的参数,比如,波特率,字符大小等等。要使用这个端口的话,你必须将头文件包含到你的程序中。这个头文件中定义了终端...
  • RTU远程终端装置

    2014-11-07 16:45:45
    RTU远程终端装置防水型测控设备,采用高性能锂电池供电,可采集各类仪表、变送器的输出信号并通过GPRS或短消息远程传输数据, DATA86RTU远程终端装置适用于不具备供电条件、环境恶劣的监测现场,广泛应用于供水、...
  • 1、采用GPRS RTU形式:适合长距离传输 无线数据采集和控制终端(RTU)是集成了模拟和数字信号采集、过程IO控制和无线数据。通过采用无线数据采集、通信诸功能于一体的高性能测控装置,可以直接接入标准变送器信号或...
  • 该版本将ttl信号输出到科学仪器中常用的BNC终端。 草图还包括一个选项,用于定义TTL触发为高电平的持续时间。 材料清单: 电路: 根据以下示意图组装电路: 山: 该代表还包括一个可以3d打印的支架,用于封装所有...
  • Linux 信号列表

    万次阅读 2015-05-26 17:40:43
    在 Linux 下,每个信号的名字都以字符 SIG 开头,每个信号和一个数字编码相对应,在头文件 signum.h 中,这些信号都被定义为正整数。信号名定义路径:/usr/include/i386-linux-gnu/bits/signum.h 列表中,编号为 1 ~...
  • Linux进程间关系之终端终端登录

    千次阅读 2017-03-01 13:05:05
    终端介绍在Linux/Unix系统中,用户总是通过终端登录系统后得到一个shell进程,进而在shell命令行上输入命令与系统进行交互。说白了,终端就是系统与用户进行“交流”的窗口,而所有在这个终端下创建的进程都“属于”...
  • Linux中信号信号处理

    千次阅读 2017-01-02 13:50:26
    Linux中信号信号处理 信号(signal)是一种软件中断,它提供了一种处理异步事件的方法,也是进程间惟一的异步通信方式。在Linux系统中,根据POSIX标准扩展以后的信号...信号由shell和终端处理器生成来引起中断,它们可
  • LoRa开发2:终端硬件平台

    千次阅读 2016-10-11 15:00:58
    讲解LoRa终端硬件设计:包括RF模块连接,MCU选型,终端接口等。
  • 串联终端匹配

    千次阅读 2013-05-04 20:38:28
    源端的输出阻抗与传输线的特征阻抗相匹配,抑制从负载端反射回来的信号发生再次反射. 串联终端匹配后的信号传输具有以下特点: A 由于串联匹配电阻的作用,驱动信号传播时以其幅度的50%向负载端传播; B 信号在...
  •  本系统采用总线结构,CPU为8031,外挂1个2718RAM,键盘为4×4矩阵键盘,通过244缓冲器与8031接上,138译码器负责给各个终端提供地址,其输出端与个芯片片选端相连。4个发光二极管分别表示电源、正弦波、余弦波、斜...
  • Linux - 终端

    千次阅读 2015-05-17 09:29:14
    C语言编写简单的菜单程序工作过程分析 getchoice() 显示程序介绍信息greet及样本菜单choices 让用户选择初始字符 main()中的do循环体 ...在输入行完成前,终端接口负责管理所有用户键盘输入,包括退格键,应用程序
  • 终端Terminal实战

    千次阅读 2021-01-15 01:10:55
    终端 Terminal 是一种用于与计算机进行交互的输入输出设备,它本身不提供运算处理功能。在大型机和小型机的时代,计算机是非常昂贵巨大的。通常计算机会被安置在单独的房间里,而操作计算机的人在另外的房间通过终端...
  • Linux系统编程(25)——终端

    千次阅读 2014-09-04 00:46:04
    在Linux系统中,用户通过终端登录...默认情况下(没有重定向),每个进程的标准输入、标准输出和标准错误输出都指向控制终端,进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误输出写也就是输出

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 76,844
精华内容 30,737
关键字:

信号输出终端