2010-04-07 6 views
1

Je crée dynamiquement une liste chaînée et initialise le premier nœud dans main(), et j'ajoute à la liste chaque fois que je lance un processus de travail. Avant que le processus de travail se termine, j'imprime la liste. En outre, j'imprime la liste dans mon gestionnaire de signal sigchld.éléments de liste liés disparu?

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

dans une fourche() 'processus de d:

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

fonctions:

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

enfin ... le gestionnaire de signal:

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

Est-il vrai que lorsque le processus de travail est en cours de fermeture, le gestionnaire de signal SIGCHLD est déclenché? Si c'est le cas, cela voudrait dire qu'après avoir imprimé l'arbre avant de quitter, la prochaine chose que je fais est dans le gestionnaire de signal qui est l'arbre d'impression ... ce qui signifierait que j'imprimerais l'arbre deux fois?

Mais l'arbre n'est pas le même. Le noeud que j'ajoute dans le processus de travail n'existe pas lorsque j'imprime dans le gestionnaire de signal ou à la fin de main(). Une idée pourquoi?

Merci, Hristo

+0

Pourriez-vous nous écrire votre code, s'il vous plaît? –

Répondre

1

Vous appelez vraisemblablement fork() pour générer le processus de travail et l'ajouter à la liste liée dans le processus enfant.

Après avoir appelé fork(), il existe maintenant deux copies indépendantes de votre liste liée: l'une appartient au parent et l'autre appartient à l'enfant. Si l'enfant ajoute un noeud, il l'ajoute à sa propre liste chaînée - la modification ne sera pas vue par le parent.

Vous devez avoir le parent ajouter le nœud à sa liste liée.

+0

merci. ça a du sens. C'est ce que je fais, et j'ajoute à la liste dans le processus fils parce que je connais l'information pour le nœud dans la liste. la raison pour laquelle j'ajoute à l'enfant est parce que je connais son PID. Je ne le sais pas dehors ...? – Hristo

+0

compris :) Merci beaucoup! – Hristo

2

le gestionnaire de signal sera appelé dans le processus parent - son arbre sera le même que lorsque vous fourchue

modifier: ++ Informations

La fourche crée une enfant avec une copie du parent. Toute modification apportée par l'enfant n'est pas vue par le parent. Ceci est pas mémoire partagée

Le SIGCHLD est appelé dans le processus parent une fois que l'enfant a terminé. Le parent affiche maintenant son arbre. L'arborescence n'a pas été modifiée et vous obtenez le même affichage.

+0

+1 Brève, mais informative. Ockham Razor :-). Mais je crois que vous pourriez ajouter quelques explications supplémentaires. – pajton

0

Le processus fils obtient une copie de l'image mémoire du parent. Ce n'est pas partagé. Pour ce faire, vous devez utiliser la mémoire partagée.

Questions connexes