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