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

Linux 的线程和信号

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

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。

  1. void os::Linux::hotspot_sigmask(Thread* thread) {  
  2.   
  3.   //Save caller's signal mask before setting VM signal mask   
  4.   sigset_t caller_sigmask;  
  5.   pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);  
  6.   
  7.   OSThread* osthread = thread->osthread();  
  8.   osthread->set_caller_sigmask(caller_sigmask);  
  9.   
  10.   pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL);  
  11.   
  12.   if (!ReduceSignalUsage) {  
  13.     if (thread->is_VM_thread()) {  
  14.       // Only the VM thread handles BREAK_SIGNAL ...   
  15.       pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);  
  16.     } else {  
  17.       // ... all other threads block BREAK_SIGNAL   
  18.       pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);  
  19.     }  
  20.   }  
  21. }  

相关推荐