我目前正在Linux操作系统下用C语言学习信号。 我有一个父进程想要将一个名为
struct Data
的整数值结构发送到它派生的子进程 - 使用 siginfo_t 结构,当我们使用 sigcation 定义信号处理程序时,该结构是信号处理程序的参数: void handler(int, siginfo_t*, void*)
父进程定义了一个
union sigval
,并将union中的sival_ptr
字段设置为
(void*) data
,其中数据是包含两个整数的 struct Data
。
然后家长使用 sigqueue(child_pid, SIGUSR1, my_sigval)
子进程使用我之前提到的 sigaction,并使用标志
SA_SIGINFO
设置 SIGUSR1 信号的信号处理程序。
在子代码的信号处理程序中,我定义了一个指针
struct Data* data
并执行此行:data = (struct Data*) (si->si_value.sival_ptr)
然后我尝试打印从父级发送的数据。
我得到的行为是子进程在打印
struct Data data
内的值之前退出,并且该行之前的所有内容都按预期执行并打印在屏幕上。
我哪里做错了?我是否没有从父级正确地将指针传递给
struct Data
?
或者我在子信号处理函数内的转换过程中做错了什么?
代码如下:
家长:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#define MY_SIGNAL SIGUSR1
// Define a structure to hold two integers
struct Data {
int value1;
int value2;
};
int main() {
// Prepare data structure
struct Data* data = (struct Data*) malloc(sizeof(struct Data));
data->value1 = 10;
data->value2 = 20;
// Fork a child process
pid_t pid = fork();
if (pid == -1) {
perror("fork failed");
return 1;
} else if (pid == 0) { // Child process
// Child process logic
execlp("./c2","c2", NULL);
//
} else { // Parent process
// Sending the signal with a pointer to the data structure
union sigval value;
value.sival_ptr = (void*) data;
// value.sival_int = 7;
sleep(1);
sigqueue(pid, MY_SIGNAL, value);
sleep(1);
}
wait(NULL);
return 0;
}
孩子:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define MY_SIGNAL SIGUSR1
// Define a structure to hold two integers
struct Data {
int value1;
int value2;
};
// Function to handle the signal
void handler(int sig, siginfo_t *si, void *unused) {
printf("Received signal: %d\n", sig);
// printf("Received signal value: %d\n", si->si_value.sival_int);
struct Data* data;
data = (struct Data*)(si->si_value.sival_ptr);
printf("Received values: %d, %d\n", data->value1, data->value2);
// Copy the received data into the allocated memory
}
int main() {
// Set up signal handler
struct sigaction sa;
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(MY_SIGNAL, &sa, NULL);
pause();
return 0;
}
你的计划不可能奏效,因为指针只在进程内有效,因为每个进程都有自己的地址空间。
即使您有两个进程之间共享的内存,也可能无法在两个进程中的同一地址找到该块。