如果一个程序向第二个程序发送信号,第二个程序可以通过它发送的信号找出第一个程序的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?
答案 0 :(得分:1)
假设您的意思是POSIX信号,那么是的。您可以通过siginfo_t
的si_pid
成员访问发件人的PID,但您需要使用sigaction
和SA_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);
注意 - 上面的代码远未完成,没有使用信号量,也没有针对多处理器环境中的竞争条件采取其他措施。