SIGTSTP和SIGSTOP的区别

本文深入探讨Linux系统中SIGTSTP和SIGCONT信号的用途和工作原理,解释SIGTSTP如何触发进程暂停并允许自定义处理方式,以及SIGCONT如何用于重新激活暂停的进程。通过实例代码展示如何实现对SIGTSTP信号的手动捕获和处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

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.

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

网上查到:SIGTSTP和SIGSTOP的唯一区别:

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

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

同时还应该注意的是,我们修改了SIGTSTP的handler之后,还是要在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 ... */

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值