linux信号スナップとsigaction関数とsigqueue関数
14792 ワード
linuxシステムのプログラミングを学ぶことについての一定の考え高い目標を避けて、必ず着実に、簡単にコードを叩いて、各種のシステム関数 を熟知しなければならない.必ずすべての知識点を食べて、これは私がなぜブログを書く原因です:ブログを書く途中で、実はこの知識点に対する理解を深めました 推荐一位博主的linuxリンク,意外にもおよび大きい!!!良いものは多く分かち合います 次はsigaction関数とsigqueue関数のコード説明です.関連知識点コードの下の注釈における 私が書くのが理解しにくい場合は、そのブロガーのリンクを参照してください.このブロガーの一番下に添付されています.
リアルタイム信号と不確実信号の違い注意:信号キュー内の信号個数は限られており(一般的には8 k)、この数を超えると古い信号を上書きするのではなく、新しい信号が破棄される.
素晴らしいリンク
linux信号キャプチャとsigaction関数とsigqueue関数の詳細な説明 sigaction関数の分析はとても良くて、ブロガーの同意を得ていませんが、良いものはやはり分かち合いたい です.
linux API , , linux linux 。
linux , :
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
void myHandler_forsigaction(int signum, siginfo_t *s_t, void *p)
{
int myint = 0;
printf("recv signum: %d
", signum);
myint = s_t->si_value.sival_int;
printf("%d %d
", myint, s_t->si_int);
}
int main()
{
pid_t pid;
int ret = 0;
struct sigaction act;
act.sa_sigaction = myHandler_forsigaction;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGINT, &act, NULL) < 0)
{
ERR_EXIT("sigaction error");
}
pid = fork();
if (pid == -1)
{
printf("fork err.....
");
return 0;
}
if (pid == 0)
{
int i = 0;
union sigval mysigval;
mysigval.sival_int = 222;
for (i = 0; i < 10; i++)
{
ret = sigqueue(getppid(), SIGINT, mysigval);
if (ret != 0)
{
printf("sigqueue err....
");
exit(0);
}
else
{
printf("sigqueue success....
");
sleep(2);
}
}
}
else if (pid > 0)
{
for(;;)
pause();
}
return 0;
}
/****************************************************************************************
1、sigaction
#include
int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
sigaction 。 0, -1。
signo 。 act , act 。
oact , oact 。
act oact sigaction :
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
void (*sa_handler)(int);
( int ), :
act.sa_handler = myHandler; //myHandler
igaction(SIGINT, &act, NULL);// signal(SIGINT, myHandler); signal igaction
void (*sa_sigaction)(int, siginfo_t *, void *);
, , , sigqueue
: , sa_flags: act.sa_flags = SA_SIGINFO;
: sa_handler ,
siginfo_t ,
。
sa_handler sa_flags 0
:sa_handler sa_sigaction
:
act.sa_sigaction = myHandler_forsigaction; //myHandler
//void myHandler_forsigaction(int signum, siginfo_t *s_t, void *p)
// s_t siginfo_t , ( , sigqueue )
siginfo_t
siginfo_t {
int si_signo; Signal number
int si_errno; An errno value
int si_code; Signal code
int si_trapno; Trap number that caused
hardware-generated signal
(unused on most architectures)
pid_t si_pid; Sending process ID
uid_t si_uid; Real user ID of sending process
int si_status; Exit value or signal
clock_t si_utime; User time consumed
clock_t si_stime; System time consumed
sigval_t si_value; Signal value // !!!
int si_int; POSIX.1b signal // !!!
void *si_ptr; POSIX.1b signal
int si_overrun; Timer overrun count; POSIX.1b timers
int si_timerid; Timer ID; POSIX.1b timers
void *si_addr; Memory location which caused fault
long si_band; Band event (was int in
glibc 2.3.2 and earlier)
int si_fd; File descriptor
short si_addr_lsb; Least significant bit of address
(since kernel 2.6.32)
}
sigset_t sa_mask;
, ,
, ,
, 。 ,
, ,
sa_mask ,
。
int sa_flags;
sa_flags , :SA_NODEFER SA_SIGINFO
SA_NODEFER ;
SA_SIGINFO sa_sigaction ,
sa_handler sa_flags 0
void (*sa_restorer)(void);
2、
sigqueue
int sigqueue(pid_t pid, int sig, const union sigval value);
( kill ), , sigaction() 。
:
id,
,
union sigval,
: 0, -1
union sigval :
typedef union sigval
{
int sival_int;
void *sival_ptr;
}sigval_t;
int sival_int;
sival_int sigaction sa_sigaction
:siginfo_t si_value.sival_int si_int
****************************************************************************************/
リアルタイム信号と不確実信号の違い
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)
void myhandle(int sig)
{
if (sig == SIGINT || sig == SIGRTMIN)
printf("recv a sig=%d
", sig);
else if (sig == SIGUSR1)
{
sigset_t s;
sigemptyset(&s);
sigaddset(&s, SIGINT);
sigaddset(&s, SIGRTMIN);
sigprocmask(SIG_UNBLOCK, &s, NULL);
}
}
void main()
{
pid_t pid;
struct sigaction act;
act.sa_handler = myhandle;
act.sa_flags = 0;
//
if ( sigaction(SIGINT, &act, NULL) <0 )
{
ERR_EXIT("sigaction SIGINT");
}
if ( sigaction(SIGRTMIN, &act, NULL) <0 )
{
ERR_EXIT("sigaction SIGINT");
}
if ( sigaction(SIGUSR1, &act, NULL) <0 )
{
ERR_EXIT("sigaction SIGINT");
}
sigset_t bset;
sigemptyset(&bset);
sigaddset(&bset, SIGINT);
sigaddset(&bset, SIGRTMIN);
sigprocmask(SIG_BLOCK, &bset, NULL);
pid = fork();
if (pid == -1)
{
ERR_EXIT("fork err");
}
//
if (pid == 0)
{
int i = 0;
int ret = 0;
union sigval v;
v.sival_int = 201;
// SIGINT
for (i=0; i<3; i++)
{
ret = sigqueue(getppid(), SIGINT, v);
if (ret == -1)
{
printf("sigqueue SIGINT err, ret: %d, errno:%d
", ret, errno);
exit(0);
}
else
{
printf("sigqueue SIGINT success
");
}
}
// SIGRTMIN
v.sival_int = 301;
for (i=0; i<3; i++)
{
ret = sigqueue(getppid(), SIGRTMIN, v);
if (ret == -1)
{
printf("sigqueue SIGRTMIN err, ret: %d, errno:%d
", ret, errno);
exit(0);
}
printf("sigqueue SIGRTMIN success
");
}
// SIGUSR1 ,
kill(getppid(), SIGUSR1);
}
while(1)
{
sleep(1);
}
printf("main....
");
}
/*******************************************************************************************
:
sigqueue SIGINT success
sigqueue SIGINT success
sigqueue SIGINT success
sigqueue SIGRTMIN success
sigqueue SIGRTMIN success
sigqueue SIGRTMIN success
recv a sig=2
recv a sig=34
recv a sig=34
recv a sig=34
:
1、 ( ) ( ) :
。( , )
2、 SIGINT SIGRTMIN , SIGUSR1 unblock。
3、 :
, pending 0,
( ),
block 0, , 。
4、
SIGINT SIGRTMIN 3 , kill SIGUSR1
: ,3 , , 。
*******************************************************************************************/
素晴らしいリンク
linux信号キャプチャとsigaction関数とsigqueue関数の詳細な説明