github.com/searKing/golang/go@v1.2.117/os/signal/example_test.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build unix
     6  
     7  package signal_test
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"runtime"
    13  	"sync"
    14  	"syscall"
    15  	"time"
    16  
    17  	signal_ "github.com/searKing/golang/go/os/signal"
    18  )
    19  
    20  func ExampleNotify() {
    21  	signal_.DumpSignalTo(syscall.Stderr)
    22  	signal_.SetSigInvokeChain(syscall.SIGUSR1, syscall.SIGUSR2, 0, syscall.SIGINT)
    23  
    24  	// Set up channel on which to send signal notifications.
    25  	// We must use a buffered channel or risk missing the signal
    26  	// if we're not ready to receive when the signal is sent.
    27  	c := make(chan os.Signal, 1)
    28  	//signal.Notify(c, syscall.SIGINT, syscall.SIGSEGV)
    29  	signal_.Notify(c, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGINT)
    30  
    31  	// simulate to send a SIGINT to this example test
    32  	go func() {
    33  		_ = syscall.Kill(syscall.Getpid(), syscall.SIGINT)
    34  	}()
    35  
    36  	var wg sync.WaitGroup
    37  
    38  	wg.Add(1)
    39  	go func() {
    40  		runtime.LockOSThread()
    41  		defer runtime.UnlockOSThread()
    42  		defer wg.Done()
    43  		for {
    44  			// Block until a signal is received.
    45  			select {
    46  			case s, ok := <-c:
    47  				if !ok {
    48  					return
    49  				}
    50  				//signal.Stop(c)
    51  				//close(c)
    52  				if s == syscall.SIGUSR1 {
    53  					_, _ = fmt.Fprintf(os.Stderr, "Previous run crashed:\n%s\n", signal_.PreviousStacktrace())
    54  					_ = syscall.Kill(syscall.Getpid(), syscall.SIGUSR2)
    55  				} else if s != syscall.SIGUSR2 {
    56  					fmt.Printf("Got signal: %s\n", s)
    57  
    58  					// just in case of windows os system, which is based on signal() in C language
    59  					// you can comment below out on unix-like os system.
    60  					signal_.Notify(c, s)
    61  				}
    62  				if s == syscall.SIGINT {
    63  					return
    64  				}
    65  
    66  			case <-time.After(time.Minute):
    67  				_, _ = fmt.Fprintf(os.Stderr, "time overseed:\n")
    68  				return
    69  			}
    70  			// set os.Stderr to pass test, for the stacktrace is random.
    71  			// stderr prints something like:
    72  			// Signal received(2).
    73  			// Stacktrace dumped to file: stacktrace.dump.
    74  			// Previous run crashed:
    75  			//  0# searking::SignalHandler::operator()(int, __siginfo*, void*) in /private/var/folders/12/870qx8rd0_d96nt6g078wp080000gn/T/___ExampleSignalAction_in_github_com_searKing_golang_go_os_signal
    76  			//  1# _sigtramp in /usr/lib/system/libsystem_platform.dylib
    77  
    78  		}
    79  	}()
    80  	wg.Wait()
    81  
    82  	// Output:
    83  	// Got signal: interrupt
    84  }