linux高階訊號傳送和接收(附帶訊息)
阿新 • • 發佈:2019-01-09
高階訊號傳送和接收
sigaction
1.可以讓訊號處理函式遮蔽訊號集
2.可以讓訊號處理函式在訊號響應的同時接收訊號源程序資訊和附帶訊息。
sigqueue
可以傳送訊號並同時傳送附帶訊息。
使用kill函式傳送訊號,sigaction可以接收到訊號傳送者的資訊,但不能接收到附帶訊息。 int sigqueue(
pid_t pid,//程序id
int sig, //訊號num
const union sigval value);//附帶資訊
getpid();//獲取當前程序id
pid_t cpid = fork();//獲取當前程序建立的子程序的id
getppid();//子程序中獲取父程序id。 子程序訊號和定時器訊號
避免殭屍程序的出現。
什麼樣的程序叫做殭屍程序:程序已經結束,但仍然佔據程序節點。
為什麼會出現殭屍程序:
父程序先於子程序結束。
如何避免殭屍程序出現:
讓父程序晚於子程序結束。
1.讓父程序等待。sleep();
2.父程序要等到子程序發訊號才會結束。
3.父程序呼叫wait函式。等待子程序死亡前傳送SIGCHLD訊號解除wait函式的阻塞。 vfork 建立多個程序。
start 啟動執行緒。 waitpid();
alarm(5);//5秒鐘後傳送14訊號。
setitimer(); #include <sys/time.h> int getitimer(
int which,
struct itimerval *value);
int setitimer(
int which, //ITIMER_REAL
const struct itimerval *value,
struct itimerval *ovalue);
sigaction
1.可以讓訊號處理函式遮蔽訊號集
2.可以讓訊號處理函式在訊號響應的同時接收訊號源程序資訊和附帶訊息。
sigqueue
可以傳送訊號並同時傳送附帶訊息。
使用kill函式傳送訊號,sigaction可以接收到訊號傳送者的資訊,但不能接收到附帶訊息。 int sigqueue(
pid_t pid,//程序id
int sig, //訊號num
const union sigval value);//附帶資訊
getpid();//獲取當前程序id
pid_t cpid = fork();//獲取當前程序建立的子程序的id
getppid();//子程序中獲取父程序id。 子程序訊號和定時器訊號
避免殭屍程序的出現。
什麼樣的程序叫做殭屍程序:程序已經結束,但仍然佔據程序節點。
為什麼會出現殭屍程序:
父程序先於子程序結束。
如何避免殭屍程序出現:
讓父程序晚於子程序結束。
1.讓父程序等待。sleep();
2.父程序要等到子程序發訊號才會結束。
3.父程序呼叫wait函式。等待子程序死亡前傳送SIGCHLD訊號解除wait函式的阻塞。 vfork 建立多個程序。
start 啟動執行緒。 waitpid();
alarm(5);//5秒鐘後傳送14訊號。
setitimer(); #include <sys/time.h> int getitimer(
int which,
struct itimerval *value);
int setitimer(
int which, //ITIMER_REAL
const struct itimerval *value,
struct itimerval *ovalue);
struct itimerval {
struct timeval it_interval; /* next value */間隔多久就傳送定時器訊號。
struct timeval it_value; /* current value */隔多久傳送第一個定時器訊號
};
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
#include <stdio.h> #include <signal.h> #include <sys/time.h> int count = 0; void hand(int s){ if(s == 14) printf("來定時器訊號了!\n"),printf("count = %d\n",count++); } int main(){ signal(14,hand); struct itimerval timer; timer.it_interval.tv_sec = 3; timer.it_interval.tv_usec = 0; timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 1; setitimer(ITIMER_REAL,&timer,NULL); while(1); return 0; }
#include <stdio.h> #include <signal.h> void hand(int s){ if(s == 2) printf("普通訊號處理函式!\n"); } void hander(int s,siginfo_t* info,void* buff){ if(s == 2){ printf("高階訊號處理函式!\n"); printf("pid:%d,uid:%d\n",info->si_pid,info->si_uid); printf("int:%x\n",info->si_int); printf("ptr:%s\n",(char*)info->si_ptr); printf("addr:%p\n",info->si_addr); printf("buff:%d\n",*( (int*)buff ) ); } } int main(){ struct sigaction act = {0}; act.sa_handler = hand; act.sa_sigaction = hander; act.sa_flags = SA_SIGINFO; sigaction(2,&act,NULL); printf("%d\n",getpid()); while(1); return 0; }