views:

50

answers:

3

I create a linked list dynamically and initialize the first node in main(), and I add to the list every time I spawn a worker process. Before the worker process exits, I print the list. Also, I print the list inside my sigchld signal handler.

in 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;

in a fork()'d process:

    // 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;

functions:

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;
}

finally... the signal handler:

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;
}

Is it true that upon the worker process exiting, the SIGCHLD signal handler is triggered? If so, that would mean that after I print the tree before exiting, the next thing I do is in the signal handler which is print the tree... which would mean i would print the tree twice?

But the tree isn't the same. The node I add in the worker process doesn't exist when I print in the signal handler or at the very end of main(). Any idea why?

Thanks, Hristo

+2  A: 

the signal handler will get called in the parent process - its tree will be the same as when you forked

edit: ++info

The fork creates a child with a copy of the parent. Any change the child makes is not seen by the parent. This is not shared memory

The SIGCHLD gets invoked in the parent process once the child finishes. The parent now displays its tree. The tree has not changed so you get the same display

pm100
+1 Brief, but informative. Ockham Razor:-). But I believe you could add some more explanation.
pajton
A: 

The child process gets a copy of the parent's memory image. It is not shared. To accomplish this, you need to use shared memory.

frankc
+1  A: 

Presumably, you are calling fork() to spawn the worker process, and adding to the linked list in the child process.

After you've called fork(), there are now two independent copies of your linked list - one belongs to the parent, and one belongs to the child. If the child adds a node, it's adding it to its own linked list - the modification won't be seen by the parent.

You need to have the parent process add the node to its linked list.

caf
thanks. that makes sense. that is what I do, and I append to the list in the child process because in there do I know the information for the node in the list. the reason I add in the child is because i know its PID. I don't know it outside...?
Hristo
figured it out :) Thanks a bunch!
Hristo