我正在尝试正确处理SIGCHLD,但我无法在处理程序中获取进程的PID,因此我可以更改结构中一个参数的值。
以下是代码:
typedef struct
{
int active_state;
int pid;
}Worker;
typedef struct
{
Worker worker;
int used_state;//this can be USED or UNUSED
}WorkersTable;
WorkersTable *table; //I put this in a shared memory map and works correctly
这是处理程序的代码。在此文件中有一个名为 dead_child_pid 的全局变量,我想要存储要使用的死孩子的pid。
void handler_SIGCHLD(int signal)
{
pid_t child_pid;
int e;
do
{
child_pid=wait3(&e,WNOHANG,NULL);
}while(child_pid>(pid_t)0);
mark_unused=1;
}
当调用handler_SIGCHLD时,最后我们将mark_unused = 1,访问以下代码:
if(mark_unused)
{
/*put the current position at the table as unused*/
int counter_find_pid=0;
while(counter_find_pid<MAX_WORKERS&&table[contador_find_pid].used_state==USED&&table[counter_find_pid].worker.pid!=dead_child_pid)
{
counter_find_pid++;
}
table[counter_find_pid].used_state=UNUSED;
}
答案 0 :(得分:1)
void handler_SIGCHLD(int signal)
{
pid_t child_pid;
int e;
do
{
child_pid=wait3(&e,WNOHANG,NULL);
}while(child_pid>(pid_t)0);
mark_unused=1;
}
有效wait3
返回值为
在child_pid
为0或-1之前,你不会离开那个循环,在这种情况下,先前的值(死亡的子pids)已被覆盖。你需要找到一种方法来保存死孩子的有效pids,同时还在循环中或改变循环。您可以将全局dead_child_pid
放在处理程序中,但要使其不稳定。
修改强>
你想要更像这样的东西但如果这是一个严肃的应用程序,这也需要增强,因为在处理死子数组下游时可能会调用处理程序。然后你必须考虑在操作时阻止SIGCHLD。
// somewhere, probably global scope
volatile currentlyDeadChilren = 0;
volatile pid_t dead_children[MAX_DEAD_CHILDREN];
void handler_SIGCHLD(int signal)
{
pid_t child_pid;
int e;
do
{
child_pid=wait3(&e,WNOHANG,NULL);
if (child_pid > 0)
dead_children[currentlyDeadChildren++] = child_pid;
}while(child_pid>(pid_t)0);
mark_unused=1;
}