Chinaunix首页 | 论坛 | 博客
  • 博客访问: 988493
  • 博文数量: 200
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 2479
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-27 15:07
文章分类

全部博文(200)

文章存档

2009年(12)

2008年(190)

我的朋友

分类:

2008-12-08 12:18:47

10.20 job-control signals

SIGCHLD

Child process has stopped or terminated.

SIGCONT

Continue process, if stopped.

SIGSTOP

Stop signal (can't be caught or ignored).

SIGTSTP

Interactive stop signal.

SIGTTIN

Read from controlling terminal by member of a background process group.

SIGTTOU

Write to controlling terminal by member of a background process group.

SIGTSTPTSTP的意思是tty stop,即在control terminal上输入了susp即,输入了ctl-zsuspend键。那么SIGTSTP被发送给进程。

网上查到:SIGTSTPSIGSTOP的唯一区别:

将进程暂停是SIGTSTP的默认action,用户可以自定义一其handler,而将进程暂停是SIGSTOP的定死的action,用户不能修改。此外,二者没什么差别,都使用SIGCONT来讲进程重新激活。

因为我们可以捕捉SIGTSTP信号,所以对于一些程序,它在被suspend的时候,她要保留当前control terminal的状态,当重新执行的时候,她要恢复control terminal的状态,因为他被暂停后,control terminal可能被别的进程使用而将control terminal的状态改变,(我们知道,一般情况下,一个进程将其标准输出和输入都设置为control terminal,对于像vi这样的程序,它在屏幕上的显示内容,应当被保存起来)所以它需要将其保存起来。

同时还应该注意的是,我们修改了SIGTSTPhandler之后,还是要在handler内部将该handler复原,然后重新触发SIGTSTP信号,来触发系统的默认处理的,这样才能将进程给suspend

下面是例子:

Figure 10.30. How to handle SIGTSTP

#include "apue.h"

#define BUFFSIZE   1024

static void sig_tstp(int);

int

main(void)

{

    int     n;

    char    buf[BUFFSIZE];

 

    /*

     * Only catch SIGTSTP if we're running with a job-control shell.

     */

    if (signal(SIGTSTP, SIG_IGN) == SIG_DFL)

        signal(SIGTSTP, sig_tstp);

 

    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)

        if (write(STDOUT_FILENO, buf, n) != n)

            err_sys("write error");

 

    if (n < 0)

        err_sys("read error");

 

    exit(0);

}

 

static void

sig_tstp(int signo) /* signal handler for SIGTSTP */

{

    sigset_t    mask;

 

    /* ... move cursor to lower left corner, reset tty mode ... */

 

    /*

     * Unblock SIGTSTP, since it's blocked while we're handling it.

     */

    sigemptyset(&mask);

    sigaddset(&mask, SIGTSTP);

    sigprocmask(SIG_UNBLOCK, &mask, NULL);

 

    signal(SIGTSTP, SIG_DFL);   /* reset disposition to default */

 

    kill(getpid(), SIGTSTP);    /* and send the signal to ourself */

 

    /* we won't return from the kill until we're continued */

 

    signal(SIGTSTP, sig_tstp);  /* reestablish signal handler */

 

    /* ... reset tty mode, redraw screen ... */

}

 

阅读(828) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~