Przejdลบ do treล›ci

๐Ÿ›‘ Advanced Signals and Job Control

Deep dive into signal handling, job control interfaces, and process communication mechanisms.

๐Ÿงญ Signal Fundamentals

Signals are asynchronous notifications sent to processes for various events.

Standard Signals

Signal Number Description Default Action
SIGHUP 1 Hangup (terminal closed) Terminate
SIGINT 2 Interrupt (Ctrl+C) Terminate
SIGQUIT 3 Quit (Ctrl+) Core dump
SIGILL 4 Illegal instruction Core dump
SIGTRAP 5 Trace/breakpoint trap Core dump
SIGABRT 6 Abort signal Core dump
SIGBUS 7 Bus error Core dump
SIGFPE 8 Floating point exception Core dump
SIGKILL 9 Kill (cannot trap) Terminate
SIGUSR1 10 User-defined signal 1 Terminate
SIGSEGV 11 Invalid memory reference Core dump
SIGUSR2 12 User-defined signal 2 Terminate
SIGPIPE 13 Broken pipe Terminate
SIGALRM 14 Alarm clock Terminate
SIGTERM 15 Termination request Terminate
SIGSTOP 17 Stop process (cannot trap) Stop
SIGTSTP 18 Terminal stop (Ctrl+Z) Stop
SIGCONT 19 Continue if stopped Continue

๐Ÿงช Signal Handling with trap

Basic Signal Trapping

1
2
3
4
5
6
7
8
# Handle Ctrl+C gracefully
trap 'echo "Interrupted!"; exit 1' INT

# Ignore termination signals
trap '' TERM

# Reset to default behavior
trap - INT

Advanced Trap Patterns

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Multiple signals with same handler
trap 'cleanup_and_exit' INT TERM HUP

# Trap all signals except KILL and STOP
trap 'log_signal_received' $(kill -l | grep -v KILL | grep -v STOP)

# Conditional trapping
if [ "$INTERACTIVE" = true ]; then
    trap 'echo "Use quit command to exit"' INT
else
    trap 'exit 1' INT
fi

๐Ÿง  Signal Information and Debugging

Signal Listing

1
2
3
4
5
6
7
8
# List all signals
kill -l

# Show signal numbers
kill -L

# Signal description
man 7 signal

Signal Sending

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# By name
kill -TERM $PID

# By number
kill -15 $PID

# To process group
kill -TERM -$PGID

# To all processes with name
pkill -TERM process_name

# To processes matching pattern
killall -TERM pattern

Signal Queueing

1
2
3
4
5
6
# Send multiple signals
for i in {1..10}; do
    kill -USR1 $PID
done

# Process handles them sequentially

๐Ÿงช Job Control Interface

Interactive Job Control

1
2
3
4
5
6
7
8
# Suspend current job (Ctrl+Z equivalent)
kill -TSTP $$

# Resume in background
kill -CONT $$

# Resume in foreground (requires terminal control)
fg %1

Programmatic Job Control

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# List jobs programmatically
jobs -p   # PIDs only
jobs -l   # Detailed info

# Bring job to foreground
fg %1

# Send job to background
bg %1

# Disown job (remove from job table)
disown %1

Job Status Checking

1
2
3
4
5
6
7
8
# Check if job exists
jobs %1 >/dev/null 2>&1 && echo "Job 1 exists"

# Wait for specific job
wait %1

# Wait for any background job
wait

๐Ÿง  Advanced Signal Patterns

Signal-Based Communication

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Parent process
child_pid=0

start_worker() {
    (
        # Worker process
        trap 'echo "Worker stopping"; exit 0' TERM
        trap 'echo "Reloading config"' USR1

        while true; do
            do_work
            sleep 1
        done
    ) &
    child_pid=$!
}

# Send signals to worker
kill -USR1 $child_pid   # Reload config
kill -TERM $child_pid   # Graceful shutdown

Signal Masking

1
2
3
4
5
6
7
8
# Block signals temporarily
trap '' INT TERM

# Critical section
perform_critical_operation

# Restore signal handling
trap - INT TERM

Signal Timing Issues

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Race condition example
trap 'flag=true' USR1

# This might miss signals
while [ "$flag" != true ]; do
    :  # Busy wait - inefficient and unreliable
done

# Better approach - use self-pipe trick
mkfifo /tmp/signal_pipe.$$
trap "echo > /tmp/signal_pipe.$$" USR1

# Wait for signal
read < /tmp/signal_pipe.$$
rm /tmp/signal_pipe.$$

๐Ÿงช Process Group Signaling

Send to Process Group

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Start process group
(
    setpgid 0 0  # Create new process group
    worker1 &
    worker2 &
    wait
) &

PGID=$!

# Send signal to entire group
kill -TERM -$PGID

Session-Wide Signaling

1
2
3
4
5
# Send to all processes in session
kill -HUP 0   # 0 means current session

# Exclude self
kill -HUP -$$ # Negative PID means process group

๐Ÿง  Signal Handling Best Practices

Robust Signal Handlers

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Reentrant signal handlers
sig_handler() {
    local sig=$1
    echo "Received signal $sig" >&2

    # Set flag for main loop to check
    signal_received=$sig
}

trap 'sig_handler INT' INT
trap 'sig_handler TERM' TERM

# Main loop checks flag
while [ "$signal_received" != "TERM" ]; do
    do_main_work
    sleep 1
done

Cleanup on Exit

1
2
3
4
5
6
7
cleanup() {
    echo "Cleaning up..." >&2
    rm -rf "$TEMP_DIR"
    unlink "$LOCK_FILE"
}

trap cleanup EXIT INT TERM

Signal Safety

Unsafe in signal handlers: - Memory allocation (malloc) - I/O operations - Most library functions

Safe operations: - Setting global flags - write(), _exit() - Simple arithmetic


๐Ÿงช Debugging Signal Issues

Signal Tracing

1
2
3
4
5
# Trace signal delivery
strace -e trace=signal ./myscript.sh

# Monitor specific signals
watch -n 1 'kill -l | head -10'

Signal Statistics

1
2
3
4
5
# View pending signals
cat /proc/$PID/status | grep -E "Sig"

# Check signal masks
cat /proc/$PID/status | grep Sig

Testing Signal Handling

1
2
3
4
5
6
7
8
9
# Automated signal testing
test_signals() {
    local pid=$1
    for sig in INT TERM HUP USR1 USR2; do
        echo "Testing signal $sig..."
        kill -$sig $pid
        sleep 1
    done
}

๐Ÿงพ Summary

  • Understand standard signal meanings and behaviors
  • Use trap for custom signal handling
  • Master job control with fg, bg, jobs, wait
  • Implement robust signal communication patterns
  • Handle race conditions with proper synchronization
  • Debug signal issues with strace and /proc
  • Follow signal safety guidelines in handlers
  • Design graceful shutdown mechanisms
  • Test signal handling thoroughly

๐Ÿ‘‰ Continue to: Shell in CI/CD