链表元素消失了?

时间:2010-04-07 21:55:09

标签: c list memory linked-list

我动态创建链接列表并初始化main()中的第一个节点,每次生成工作进程时都会添加到列表中。在工作进程退出之前,我打印列表。另外,我在sigchld信号处理程序中打印列表。

在main()中:

head = NULL;
tail = NULL;
// linked list to keep track of worker process
dll_node_t *node;
node = (dll_node_t *) malloc(sizeof(dll_node_t)); // initialize list, allocate memory
append_node(node);
node->pid = mainPID; // the first node is the MAIN process
node->type = MAIN;

在fork()'进程中:

    // add to list
    dll_node_t *node;
    node = (dll_node_t *) malloc(sizeof(dll_node_t));
    append_node(node);
    node->pid = mmapFileWorkerStats->childPID;
    node->workerFileName = mmapFileWorkerStats->workerFileName;
    node->type = WORK;

功能:

void append_node(dll_node_t *nodeToAppend) {
    /*
     * append param node to end of list
     */

    // if the list is empty
    if (head == NULL) {
        // create the first/head node
        head = nodeToAppend;
        nodeToAppend->prev = NULL;
    } else {
        tail->next = nodeToAppend;
        nodeToAppend->prev = tail;
    }

    // fix the tail to point to the new node
    tail = nodeToAppend;
    nodeToAppend->next = NULL;
}

最后......信号处理程序:

void chld_signalHandler() {
    dll_node_t *temp1 = head;
    while (temp1 != NULL) {
        printf("2. node's pid: %d\n", temp1->pid);
        temp1 = temp1->next;
    }

    int termChildPID = waitpid(-1, NULL, WNOHANG);
    dll_node_t *temp = head;
    while (temp != NULL) {
        if (temp->pid == termChildPID) {
            printf("found process: %d\n", temp->pid);
        }
        temp = temp->next;
    }
    return;
}

在工作进程退出时,是否触发了SIGCHLD信号处理程序?如果是这样,那就意味着在我退出之前打印树之后,我接下来要做的就是打印树的信号处理程序...这意味着我会打印树两次?

但树不一样。当我在信号处理程序中打印或在main()的最末端打印时,我在工作进程中添加的节点不存在。知道为什么吗?

谢谢, Hristo

3 个答案:

答案 0 :(得分:2)

信号处理程序将在父进程中被调用 - 它的树将与分叉时的树相同

编辑:++ info

fork会创建一个包含父项副本的子项。父母不会看到孩子做出的任何改变。这是共享内存

一旦子项完成,SIGCHLD将在父进程中调用。父级现在显示其树。树没有改变,所以你得到相同的显示

答案 1 :(得分:1)

据推测,您正在调用fork()来生成工作进程,并添加到子进程中的链接列表。

在您调用fork()之后,现在有两个独立的链表副本 - 一个属于父级,一个属于子级。如果孩子添加了一个节点,它会将其添加到自己的链表中 - 父母不会看到修改。

您需要让进程将节点添加到其链接列表中。

答案 2 :(得分:0)

子进程获取父进程内存映像的副本。它不是共享的。为此,您需要使用共享内存。