You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向进程组内除发送进程外的所有进程发送信号?

Great question! The kill(0, SIGUSR1) trick is super handy for broadcasting signals to your entire process group, but excluding yourself requires a bit more work since there’s no direct system call that does this out of the box. Let’s walk through the most reliable approaches, plus a quick hack if you’re in a pinch.

Method 1: Iterate over your process group and skip your PID (most robust)

This method involves explicitly finding every process in your group except your own, then sending the signal to each one individually. It’s the most reliable because it avoids race conditions and doesn’t interfere with your signal handling. Here’s how to implement it in C:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>

int main() {
    pid_t my_pid = getpid();
    pid_t my_pgid = getpgrp(); // getpgid(0) works too

    // Open the /proc directory to scan running processes
    DIR *proc_dir = opendir("/proc");
    if (!proc_dir) {
        perror("Failed to open /proc");
        return EXIT_FAILURE;
    }

    struct dirent *entry;
    while ((entry = readdir(proc_dir)) != NULL) {
        // Skip non-numeric entries (only numeric dirs are process IDs)
        if (!isdigit(entry->d_name[0])) {
            continue;
        }

        pid_t current_pid = atoi(entry->d_name);
        if (current_pid == my_pid) {
            continue; // Skip our own process
        }

        // Check if this process is in our process group
        pid_t current_pgid = getpgid(current_pid);
        if (current_pgid == -1) {
            // Process might have exited between scanning /proc and calling getpgid
            continue;
        }

        if (current_pgid == my_pgid) {
            // Send SIGUSR1 to the matching process
            if (kill(current_pid, SIGUSR1) == -1) {
                fprintf(stderr, "Failed to send signal to PID %d: ", current_pid);
                perror("");
            }
        }
    }

    closedir(proc_dir);
    return EXIT_SUCCESS;
}

Key notes about this code:

  • We use /proc (a pseudo-filesystem that exposes process details) to find all running processes.
  • getpgid() checks if a process belongs to our group. Processes might exit right after we detect them, so we gracefully skip any errors from getpgid() or kill().
  • This works on all Linux systems (and most Unix-like systems with /proc support).
Method 2: Temporarily ignore the signal (quick but with caveats)

If you want a simpler solution and don’t mind a small risk, you can temporarily ignore SIGUSR1 before calling kill(0, SIGUSR1). This way, the signal is sent to your entire group (including you), but your process won’t react to it.

Here’s the code:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    struct sigaction original_handler;
    // Save our original SIGUSR1 handler first
    if (sigaction(SIGUSR1, NULL, &original_handler) == -1) {
        perror("Failed to save original handler");
        return EXIT_FAILURE;
    }

    // Temporarily ignore SIGUSR1
    struct sigaction ignore_action = {0};
    ignore_action.sa_handler = SIG_IGN;
    if (sigaction(SIGUSR1, &ignore_action, NULL) == -1) {
        perror("Failed to set ignore handler");
        return EXIT_FAILURE;
    }

    // Broadcast to the process group (we'll ignore our own signal)
    kill(0, SIGUSR1);

    // Restore the original signal handler
    if (sigaction(SIGUSR1, &original_handler, NULL) == -1) {
        perror("Failed to restore original handler");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

Caveats to watch out for:

  • Race condition: If another process sends SIGUSR1 to you while you’re ignoring it, you’ll miss that signal entirely.
  • This only prevents your handler from running—it doesn’t stop the signal from being delivered. If the signal’s default action was termination (like SIGTERM), this wouldn’t save you (but SIGUSR1 is user-defined, so this is usually safe).
For shell scripts

If you’re working in a bash/zsh shell, you can use pkill to do this in one line:

# Get our process group ID and trim whitespace
PGID=$(ps -o pgid= $$ | xargs)
# Send SIGUSR1 to all processes in the group except our own
pkill -g "$PGID" -v -p $$ -USR1

Breakdown of the pkill flags:

  • -g "$PGID": Target all processes in our process group
  • -v: Invert the match (exclude the PID we specify)
  • -p $$: Exclude our own shell process (PID stored in $$)
  • -USR1: Send the SIGUSR1 signal

内容的提问来源于stack exchange,提问作者Zeno Raiser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:23:11