两个程序之间的信号

时间:2013-03-01 03:18:22

标签: c signals

如果一个程序向第二个程序发送信号,第二个程序可以通过它发送的信号找出第一个程序的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();
}

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

3 个答案:

答案 0 :(得分:1)

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

非POSIX系统(例如Windows)甚至可能没有信号的概念(至少不符合POSIX意义),所以这些都不适用。

答案 1 :(得分: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
$

答案 2 :(得分:-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);

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