4

如果一个程序向第二个程序发送信号,那么第二个程序能否仅通过它发送的信号找出第一个程序的pid是什么?

第一个程序:(代码不完整,信号是重点)

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

void my_handler(int);


int main(int argc, char *argv[]){


    FILE *fp;
    fp=fopen(argv[1], "w");

    kill(atol(argv[2]),SIGUSR1);
}

第二个程序:

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

void my_handler(int signum){
            if (signum == SIGUSR1)
            {
                    printf("Received SIGUSR1!\n");
            }
}

int main(int argc, char *argv[]){
    int pid;
    pid=getpid();
    printf("PID: %d\n", pid);

    signal(SIGUSR1, my_handler);

    pause();
}

有办法吗?或者我应该以SIGUSR1某种方式将第一个程序的 pid 放入第二个程序可以找出 pid?

4

3 回答 3

1

假设您在一个与 POSIX 充分兼容的系统上,那么如果您使用 设置信号处理sigaction(),如果您指定一个采用siginfo_t指针的信号处理程序,并且您将 SA_SIGINFO 指定为标志之一,那么您可以获得信息:

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static siginfo_t sig_info;
static volatile sig_atomic_t sig_num;
static void *sig_ctxt;

static void catcher(int signum, siginfo_t *info, void *vp)
{
    sig_num = signum;
    sig_info = *info;
    sig_ctxt = vp;
}

static void set_handler(int signum)
{
    struct sigaction sa;
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = catcher;
    sigemptyset(&sa.sa_mask);

    if (sigaction(signum, &sa, 0) != 0)
    {
        int errnum = errno;
        fprintf(stderr, "Failed to set signal handler (%d: %s)\n", errnum, strerror(errnum));
        exit(1);
    }
}

static void prt_interrupt(FILE *fp)
{
    if (sig_num != 0)
    {
        fprintf(fp, "Signal %d from PID %d\n", sig_info.si_signo, (int)sig_info.si_pid);
        sig_num = 0;
    }
}

int main(void)
{
    set_handler(SIGINT);
    pause();
    prt_interrupt(stdout);
    return(0);
}

编译为“catch”并运行:

$ ./catch &
[1] 31165
$ kill -2 31165
Signal 2 from PID 26983
$ echo $$
26983
[1]+  Done                    ./catch
$
于 2013-03-01T05:13:22.890 回答
1

假设您的意思是 POSIX 信号,那么是的。si_pid您可以通过 的成员访问发件人的 PID siginfo_t,但您需要使用sigactionSA_SIGINFO标志来定义您的处理程序。

非 POSIX 系统(例如 Windows)甚至可能没有信号的概念(至少在 POSIX 意义上没有),因此这些都不适用。

于 2013-03-01T03:24:14.427 回答
-1

您可以在两个进程之间创建共享内存。从第一个进程开始,使用 getpid() 获取 pid,并将其保存到共享内存区域。

ShmID   = shmget(PidKey, sizeof(pid_t), IPC_CREAT | 0666);
ShmPTR  = (pid_t *) shmat(ShmID, NULL, 0);

在第二个进程中,在您的处理程序中,只需将您的 c 程序附加到共享内存区域。

void my_handler(int signum)
{
 if (signum == SIGUSR1)
 {

  ShmID   = shmget(PidKey, sizeof(pid_t), 0666);
  ShmPTR  = (pid_t *) shmat(ShmID, NULL, 0);
  pid     = *ShmPTR
 }
}

在程序结束时,清理共享内存。

shmdt(ShmPTR);
shmctl(ShmID, IPC_RMID, NULL);

注意 - 上面的代码远未完成,没有使用信号量,也没有针对多处理器环境中的竞争条件采取其他措施。

于 2013-03-01T04:02:36.933 回答