Java 中关于信号的处理在Linux下的实现

Linux 的线程和信号

基于 NPTL 的线程库,多线程应用中的每个线程有自己独特的线程 ID,并共享同一个进程ID。应用程序可以通过调用 kill(getpid(),signo) 将信号发送到进程,如果进程中当前正在执行的线程没有阻碍此信号,则会被中断,线号处理函数会在此线程的上下文背景中执行。应用程序也可以通过调用 pthread_kill(pthread_t thread, int sig)将信号发送给指定的线程,则线号处理函数会在此指定线程的上下文背景中执行。

Java 中关于信号的处理在Linux下的实现

Java里信号掩码的集合

unblocked_sigs

 

SIGILL

SIGSEGV

SIGBUS

SIGFPE

SR_signum

SHUTDOWN1_SIGNAL(SIGHUP)

SHUTDOWN2_SIGNAL(SIGINT)

SHUTDOWN3_SIGNAL(SIGTERM)

 

vm_sigs

 

BREAK_SIGNAL (SIGQUIT)

 

allowdebug_blocked_sigs

 

SHUTDOWN1_SIGNAL(SIGHUP)

SHUTDOWN2_SIGNAL(SIGINT)

SHUTDOWN3_SIGNAL(SIGTERM)

 

SIG_BLOCK

 

NULL

 

在多线程的应用中,每个线程可以通过调用pthread_signmask()设置本线程的信号掩码,可以设置阻塞的信号,但信号SIGKILL/SIGSTOP是不能被设置成阻塞的。

在java中,每个线程都设置了在表格中的信号掩码,特别提到的是vm_sigs,这是只有一个quit 的信号结合,当没有设置启动参数 -Xrs (=ReduceSignalUsage)的时候,其他的线程设置成阻塞的,除了vm thread。

void os::Linux::hotspot_sigmask(Thread* thread) {        //Save caller's signal mask before setting VM signal mask      sigset_t caller_sigmask;     pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);        OSThread* osthread = thread->osthread();     osthread->set_caller_sigmask(caller_sigmask);        pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL);        if (!ReduceSignalUsage) {       if (thread->is_VM_thread()) {         // Only the VM thread handles BREAK_SIGNAL ...          pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);       } else {         // ... all other threads block BREAK_SIGNAL          pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);       }     }   }  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyjgzf.html