4

1つのプログラムが2番目のプログラムに信号を送信した場合、2番目のプログラムは、送信された信号だけで最初のプログラムの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);
}

2番目のプログラム:

#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何らかの方法で配置すると、2番目のプログラムがpidを把握できるようにする必要がありますか?

4

3 に答える 3

1

あなたがPOSIXシグナルを意味すると仮定すると、そうです。si_pidのメンバーを介して送信者のPIDにアクセスできますが、ハンドラーを定義するにはとフラグをsiginfo_t使用する必要があります。sigactionSA_SIGINFO

非POSIXシステム(Windowsなど)には信号の概念すら含まれていない可能性があるため(少なくともPOSIXの意味では)、これは当てはまりません。

于 2013-03-01T03:24:14.427 に答える
1

十分にPOSIX互換のシステムを使用していると仮定すると、で信号処理を設定しsigaction()、ポインターを受け取る信号ハンドラーを指定しsiginfo_t、フラグの1つとして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

2つのプロセス間で共有メモリを作成できます。最初のプロセスから、getpid()を使用してpidを取得し、共有メモリ領域に保存します。

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

2番目のプロセスでは、ハンドラー内で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 に答える