我动态创建链接列表并初始化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
答案 0 :(得分:2)
信号处理程序将在父进程中被调用 - 它的树将与分叉时的树相同
编辑:++ info
fork会创建一个包含父项副本的子项。父母不会看到孩子做出的任何改变。这是不共享内存
一旦子项完成,SIGCHLD将在父进程中调用。父级现在显示其树。树没有改变,所以你得到相同的显示
答案 1 :(得分:1)
据推测,您正在调用fork()
来生成工作进程,并添加到子进程中的链接列表。
在您调用fork()
之后,现在有两个独立的链表副本 - 一个属于父级,一个属于子级。如果孩子添加了一个节点,它会将其添加到自己的链表中 - 父母不会看到修改。
您需要让父进程将节点添加到其链接列表中。
答案 2 :(得分:0)
子进程获取父进程内存映像的副本。它不是共享的。为此,您需要使用共享内存。