【问题标题】:Bizzare printing of C program - Linux terminalC程序的奇葩打印——Linux终端
【发布时间】:2014-12-08 11:57:11
【问题描述】:

我正在编写一个程序来在 C 和 Linux 环境中试验分叉和信号。

该程序以各种方式创建许多子进程,每个进程在其开始和结束时打印一条特定的消息,而大多数进程自己创建子进程。父母总是在他们终止之前等待他们所有的孩子,并且在他们终止之前和他们的孩子终止之后睡一段固定的时间。

于是我执行了程序,在终端中,立马打印了一些信息,但是随后出现了终端的插入提示,好像程序已经终止,终端准备好接受进一步的命令,但是程序正在执行的继续打印该点之后的其余消息。

我可以在程序打印的最后一条消息之后立即编写任何新命令,而不会出现任何新提示。可能是什么原因造成的?

编辑:发现问题 - 我需要在 'main' 中的 'if' 分支的末尾添加以下代码:

else{
    int status;
    waitpid(id,&status,0)
}  

终端输出(示例):

user@oslab:~/workspace/Ex2.1 $ ./a.out ./forktree/proc.tree                                                                       
Hello I am process A and I just got forked by DAD!
Hello I am process B and I just got forked from A!
Hello I am process C and I just got forked from A!
Hello I am process D and I just got forked from A!
Hello I am process E and I just got forked from B!
Hello I am process F and I just got forked from B!
user@oslab:~/workspace/Ex2.1 $ I am process C, I finished creating 0 children, and now I am exiting.Farewell!
I am process D, I finished creating 0 children, and now I am exiting.Farewell!
I am process E, I finished creating 0 children, and now I am exiting.Farewell!
I am process F, I finished creating 0 children, and now I am exiting.Farewell!
I am process B, I finished creating 2 children, and now I am exiting.Farewell!
I am process A, I finished creatind 3 children, and now I am exiting.Farewell!

以下是完整的代码,您可以根据需要进行任何研究。
tree.h 定义了一个树状结构,它总体上定义了必须创建的进程的“树”。

DAD 是第一个进程,位于所述树的根之下。

下面是我的程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>  
#include <sys/prctl.h>  
#include <sys/types.h>  
#include <sys/wait.h>  
#include "forktree/tree.h"  
#include "forktree/tree.c"  
#define SLEEP_TIME 5

//BY NO MEANS READY TO RUN
//update:most functionality is now ready.

int first_of_the_year(struct tree_node *base);//Will only be used by the root of the tree,to make         recursion easier
int recurse_me(struct tree_node *base,char *parent_name);//will be used by every other forked process

int main(int argc, char *argv[]){
    struct tree_node *base = get_tree_from_file(argv[1]);
    //struct tree_node *rocket = NULL;
    char *parent_name = NULL;
    pid_t id = fork();
    if(id<0) {
        perror("fork");

    } else if (id == 0) {

        first_of_the_year(base);

    }
    return 0;

}

//forked recursions will return -1, while shallow recursions resulting in a successful fork from     parents will retun 0.
//that will prevent the children from re-creating multiple copies of other processes, while going     up (returning from) the recursion.

int first_of_the_year(struct tree_node *base){
    printf("Hello I am process %s and I just got forked by DAD!\n",base->name);
    int i = 0;
    int flag = 0;
    while((base->nr_children>i)&&(flag !=-1)){
        flag = recurse_me(base->children + i,base->name);
        i++;        
    }
    if (flag==0){
        int count = base->nr_children;
        int status;
        for (i = 0; i < count; i++) {
            wait(&status);
        }
        sleep(SLEEP_TIME);
        printf("I am process %s, I finished creatind %u children, and now I am     exiting.Farewell!\n",base->name,base->nr_children);
    }
    return 0;
}


int recurse_me(struct tree_node *base,char *parent_name){
    int id;
    id = fork();

    if(id<0) {
        perror("fork");

    } else if (id == 0) {
        printf("Hello I am process %s and I just got forked from %s!\n",(base-    >name),parent_name);
        int i=0;
        int flag=0;
        while((base->nr_children>i)&&(flag !=-1)){
            flag = recurse_me(base->children + i,base->name);
            i++;
        }
        if (flag==0){
            int count = base->nr_children;
            int status;
            for (i = 0; i < count; i++) {
                wait(&status);
            }
        sleep(SLEEP_TIME);
        printf("I am process %s, I finished creating %u children, and now I am exiting.Farewell!\n",base->name,base->nr_children);
    }
    return -1;
}

return 0;


}  

这里是tree.h:

#ifndef TREE_H
#define TREE_H

/******************************************************************************
 * Data structure definitions
 */

#define NODE_NAME_SIZE 16
/* tree node structure */
struct tree_node {
    unsigned          nr_children;
    char              name[NODE_NAME_SIZE];
    struct tree_node  *children;
};


/****************************************************************************** 
 * Helper Functions
 */

/* returns the root node of the tree defined in a file */
struct tree_node *get_tree_from_file(const char *filename);

void print_tree(struct tree_node *root);

#endif /* TREE_H */

【问题讨论】:

  • 在不知道您如何生成进程的“各种方式”的情况下,我们很可能无法为您提供帮助。还尝试发布一个说明您的问题的最小示例。
  • Parents always wait for all their children before they terminate, 在你的情况下不太可能。
  • 好吧,“各种方式”基本上意味着只使用 fork,但我主要使用递归函数(作为练习的一部分询问)并使用特定标志,以便孩子们继续递归不会重新制作只有父母应该制作的其他孩子。我将发布终端的输出。发布整个代码会有帮助吗?
  • 当然,拥有源代码会有所帮助。请将其添加到问题中。
  • 添加的代码以及示例输出

标签: c linux terminal


【解决方案1】:

我认为父进程可能已终止,而子进程未终止。在您的情况下,主函数可能在子进程之前终止。

【讨论】:

    【解决方案2】:

    fork 在后台启动一个进程。父进程完成后,控制权返回给 shell,并显示新的提示。

    要让父母等到孩子完成,你可以做类似的事情:

    else {
        printf("Parent process is terminating...\n");
        wait(NULL);
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      我刚刚注意到了这个问题。 DAD,第一个进程,不等待树的根。所以它在所有孩子和子孩子返回之前退出。添加必要的代码等待树的根进程解决了问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-10
        • 1970-01-01
        • 1970-01-01
        • 2010-11-23
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        相关资源
        最近更新 更多