信号的中断与系统调用的重起
时间:2006-03-10 来源:rwen2012
#include <signal.h>
int sigaction(ints signo, const struct sigaction *act,
struct sigaction *oact) ;
struct sigaction {
void (*sa_handler)(); /* addr of signal handler,
or SIG_IGN, or SIG_DFL */
sigset_t sa_mask; /* additional signals to block */
int sa_flags; /* signal options*/
} ;
当更改信号动作时,如果sa _handler指向一个信号捕捉函数(不是常数SIG_IGN或SIG_DFL),则sa_mask字段说明了一个信号集,在调用信号捕捉函数之前,该信号集要加到进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字恢复为原先值。这样,在调用信号处理程序时就能阻塞某些信号。在信号处理程序被调用时,系统建立的新信号屏蔽字会自动包
括正被递送的信号。因此保证了在处理一个给定的信号时,如果这种信号再次发生,那么它会被阻塞到对前一个信号的处理结束为止。
A. 可自动重起的signal()的实现:
#include <signal.h>
#typpdef void Sigfunc(int signo);
Sigfunc *signal(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM)
{
#ifdef SA_INTTERRUPT //SUNOS
act.flags |= SA_INTTERRUPT;
#endif
}
else // for other signal
{
#ifdef SA_RESTART //SVR, 4.3+BSD
act.flag |= SA_RESTART;
#endif
}
if (sigaction(signo, &act, &oac) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
注: 在if语句中,我们检查是否为SIGALRM信号,如果是,且系统定义了
SA_INTERRUPT(SUNOS),即为SUNOS,该系统默认的系统调用是自
动重起的,我们阻止该信号中断的系统调用重起,因为我们要用该信号
中断I/O操作,实现定时的功能.
接着的else语句中的信号为SIGALRM之外的其他信号,且系统定义了
SA_RESTART,即为SVR4或4.3+BSD类系统,该类系统中默认的系统
调用是不可重起的,所以应该加上SA_RESTART标志,使由这些信号中
断的系统调用自动重起.
B. 不可重起的signal_intr()实现:
Sigfunc *signal_intr(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(act.sa_mask);
act.sa_flags = 0;
#ifdef SA_INTTERRUPT //SUNOS
act.flags |= SA_INTTERRUPT;
#endif
if (sigaction(signo, &act, &oac) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
注: 只有SUNOS为自动重起的,其他为不自动重起的,所以只要将SUNOS标
志为非自动重起即可.如上.
int sigaction(ints signo, const struct sigaction *act,
struct sigaction *oact) ;
struct sigaction {
void (*sa_handler)(); /* addr of signal handler,
or SIG_IGN, or SIG_DFL */
sigset_t sa_mask; /* additional signals to block */
int sa_flags; /* signal options*/
} ;
当更改信号动作时,如果sa _handler指向一个信号捕捉函数(不是常数SIG_IGN或SIG_DFL),则sa_mask字段说明了一个信号集,在调用信号捕捉函数之前,该信号集要加到进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字恢复为原先值。这样,在调用信号处理程序时就能阻塞某些信号。在信号处理程序被调用时,系统建立的新信号屏蔽字会自动包
括正被递送的信号。因此保证了在处理一个给定的信号时,如果这种信号再次发生,那么它会被阻塞到对前一个信号的处理结束为止。
A. 可自动重起的signal()的实现:
#include <signal.h>
#typpdef void Sigfunc(int signo);
Sigfunc *signal(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM)
{
#ifdef SA_INTTERRUPT //SUNOS
act.flags |= SA_INTTERRUPT;
#endif
}
else // for other signal
{
#ifdef SA_RESTART //SVR, 4.3+BSD
act.flag |= SA_RESTART;
#endif
}
if (sigaction(signo, &act, &oac) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
注: 在if语句中,我们检查是否为SIGALRM信号,如果是,且系统定义了
SA_INTERRUPT(SUNOS),即为SUNOS,该系统默认的系统调用是自
动重起的,我们阻止该信号中断的系统调用重起,因为我们要用该信号
中断I/O操作,实现定时的功能.
接着的else语句中的信号为SIGALRM之外的其他信号,且系统定义了
SA_RESTART,即为SVR4或4.3+BSD类系统,该类系统中默认的系统
调用是不可重起的,所以应该加上SA_RESTART标志,使由这些信号中
断的系统调用自动重起.
B. 不可重起的signal_intr()实现:
Sigfunc *signal_intr(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(act.sa_mask);
act.sa_flags = 0;
#ifdef SA_INTTERRUPT //SUNOS
act.flags |= SA_INTTERRUPT;
#endif
if (sigaction(signo, &act, &oac) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
注: 只有SUNOS为自动重起的,其他为不自动重起的,所以只要将SUNOS标
志为非自动重起即可.如上.
相关阅读 更多 +
排行榜 更多 +