简体   繁体   English

C程序的Bizzare打印-Linux终端

[英]Bizzare printing of C program - Linux terminal

I am making a program to experiment with forking and signals in C and Linux environment. 我正在编写一个程序,以在C和Linux环境中试验分叉和信号。

The program creates many child processes with various ways, and each process prints a specific message at its beginning and at its end, while most of them create children themselves. 该程序以各种方式创建许多子进程,每个进程在其开始和结束时都打印一条特定的消息,而大多数进程自己创建子进程。 Parents always wait for all their children before they terminate, and also sleep for a fixed amount of time before they terminate and after their children terminate. 父母总是在等待所有孩子离婚前等待,并且在他们离婚之前和孩子离婚之后还要睡一段固定的时间。

So I execute the program, and in the terminal, some messages are printed right away, but then the insert prompt of the terminal appears, as if the program has terminated and the terminal is ready to accept further commands, but the program being executed proceeds to print the rest of the messages AFTER that point. 因此,我执行了该程序,并在终端中立即打印了一些消息,但是随后出现终端的插入提示,好像程序已终止并且终端已准备好接受其他命令,但是正在执行的程序仍在继续在此之后打印其余消息。

I am able to write any new commands right after the last message printed by the program, without any new prompt appearing. 我能够在程序最后一条消息之后立即编写任何新命令,而不会出现任何新提示。 What might be causing that? 是什么原因造成的?

EDIT:Problem found - I need to add the following code at the end of 'if' branch in'main': 编辑:发现问题-我需要在“ main”的“ if”分支的末尾添加以下代码:

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

The terminal output (an example) : 终端输出(示例):

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!

Below is the whole code, to make any research you want. 以下是完整的代码,可以进行您需要的任何研究。
The tree.h defines a tree-like structure, which overall defines the "Tree" of processes that has to be made. tree.h定义了一个类似树的结构,该结构总体上定义了必须执行的进程的“树”。

DAD is the very first process, below the root of the said tree. DAD是第一个过程,位于所述树的根下方。

Below is my program: 下面是我的程序:

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


}  

And here is tree.h: 这是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 */

I think the parent process might have terminated where as the child process not terminated. 我认为父进程可能已终止,而子进程未终止。 In your case , the main function might have terminated before the child processes. 在您的情况下,main函数可能在子进程之前终止。

fork starts a process in the background. fork在后台启动一个进程。 Once the parent process finishes, control is returned to shell and a new prompt is shown. 父进程完成后,控制权将返回到Shell并显示新的提示。

To let the parent wait until the child is done, you can do something similar: 要让父母等到孩子完成后,可以执行类似的操作:

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

I just noticed the problem. 我只是注意到了问题。 DAD, the very first process, does not wait for the root of the tree. DAD,第一个过程,不等待树的根。 So it exits before all the children and sub-children return. 因此,它在所有子级和子级子返回之前退出。 Adding the necessary code to wait for the root process of the tree solved the problem. 添加必要的代码以等待树的根进程即可解决该问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM