在使用FreeBSD和C语言完成后获取子进程的PID

时间:2013-12-06 00:45:31

标签: c process freebsd sigchld

我正在尝试正确处理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;
    }

1 个答案:

答案 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返回值为

  1. 孩子的pid
  2. 0如果有孩子没有改变状态
  3. 错误
  4. -1
  5. 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;
    }