关于用fork()在我的虚拟外壳后台进程和子进程 [英] Regarding background processes using fork() and child processes in my dummy shell

查看:185
本文介绍了关于用fork()在我的虚拟外壳后台进程和子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创造C.一个简单的shell程序我需要做的是提供与它们可以运行其他本地程序提示用户。我能做到这部分精细,用叉子()在父进程等待()的孩子,而孩子execvp()的程序。

I'm trying to create a simple shell program in C. What I need it to do is provide the user with a prompt in which they can run other local programs. I can do that part fine, using a fork() in which the parent process waits() on the child,and the child execvp()'s the program.

然而,如果'和;'字符被追加到用户的命令结束后,我需要他们的程序在后台运行,这意味着我需要父母不等待的子进程,而是立即返回提示给用户,同时允许后台进程继续跑,bbut不允许其显示在屏幕上的任何内容。我只是希望能够检查它通过ps命令仍然存在。

However, if the '&' character is appended to the end of the user's command, I need their program to run in the background, meaning I need the parent to NOT wait on the child process but instead immediately return the prompt to the user, while allowing the background process to continue to run, bbut not allowing it to display anything on the screen. I just want to be able to check that it still exists via ps command.

我试图了解背后用fork()创建一个孩子的想法,然后再有孩子叉()创建各种各样的孙子,然后立即退出() - ING子进程。即孤儿孙子。据说,这使得家长还等上了孩子,但因为孩子有效地几乎立即结束,就像它不会等待呢?一些关于僵尸的疯狂?我不知道。几个网站我遇到似乎推荐这作为一种在后台运行的进程。

I tried to understand the idea behind using fork() to create a child, then have the child fork() again to create a grandchild of sorts, then immediately exit()-ing the child process. i.e., orphan the grandchild. Supposedly this allows the parent to still wait on the child, but since the child effectually ends almost immediately, it's like it doesn't wait at all? Something about zombie madness? I don't know. Several sites I've come across seem to recommend this as a way to run a process in the background.

然而,当我尝试这样做,我得到的野物与程序的流程发生,背景进程继续显示在屏幕上输入,我真的不知道在哪里从这里走。

However, when I try to do this, I get wild things happening with the flow of the program, the 'background' process continues to display input on the screen, and I'm really not sure where to go from here.

这是我执行code,我敢肯定,是完全错误的。我只是想知道,如果这整个事情孙子,甚至我需要走的路线,如果是这样,有什么错我的code?

This is my implementation of the code, which I'm sure is quite wrong. I'm just wondering if this whole grandchild thing is even the route I need to take,and if so, what's wrong with my code?

36 int main(int argc, char *argv[])
37 {
38     char buffer[512];
39     char *args[16];
40     int background;
41     int *status;
42     size_t arg_ct;
43     pid_t pid;
44 
45     while(1)
46     {
47         printf("> ");
48         fgets(buffer, 512, stdin);
49         parse_args(buffer, args, 16, &arg_ct);
50 
51         if (arg_ct == 0) continue;
52 
53         if (!strcmp(args[0], "exit"))
54         {
55             exit(0);
56         }
57 
58         pid = fork();  //here I fork and create a child process
61 
62         if (pid && !background)  //i.e. if it's the parent process and don't need to run in the background (this is the part that seems to work)
63         {
64             printf("Waiting on child (%d).\n", pid);
65             pid = wait(status);
66             printf("Child (%d) finished.\n", pid);
67         }
68         else
69         {
70             if (background && pid == 0) { //if it's a child process and i need to run the command in background
71                
72                 pid = fork(); //fork child and create a grandchild
73                 if (pid) exit(0); //exit child and orphan grandchild
74                 
75                 execvp(args[0], args); //orphan execs the command then exits
76                 exit(1);
77 
78             } else exit(0);
79         }
80     }
81     return 0;
82 }

P.S。要清楚,我需要,我在后台运行,永远不再发出声音的过程,即使它有打印报表或某事的无限循环。我只是想确保它仍在通过PS -a什么后台运行。

P.S. To be clear, I need the process that I'm running in the background to never make a sound again, even if it's got an infinite loop of print statements or something. I just want to make sure that it is still running in the background via ps -a or something.

很抱歉的混乱的解释,我只是不知道如何更好解释。

Sorry for the confusing explanation I just don't know how to explain it any better.

在此先感谢

P.P.S我将实现它,这样以后每次命令将确定的背景,遗憾的混乱

P.P.S I'll be implementing it so that each subsequent command will determine the boolean value of 'background', sorry for the confusion

推荐答案

您不想使用双 - 叉()方法在shell - 这是编写特别希望通过跑他们的壳监督逃脱守护进程。

You do not want to use the double-fork() method in a shell - that is for writing daemons that specifically want to escape from supervision by the shell that ran them.

相反,复制&放的行为方式; 在现有的炮弹是调用叉(),那么在孩子通话 setpgid(0,0); 来把孩子进入一个新的进程组的。父只是继续在(也许是印刷孩子的 PID 之后) - 它不叫等待()

Instead, the way to duplicate the behaviour of & in existing shells is to call fork(), then in the child call setpgid(0, 0); to put the child into a new process group. The parent just continues on (perhaps after printing the PID of the child) - it doesn't call wait().

每个终端只能有一个前台进程组,这是当前允许输出发送给终端的处理组。这仍将是进程组,其中你的shell是一个成员,所以你的shell将保持在前台。

Each terminal can have only one foreground process group, which is the process group which is currently allowed to send output to the terminal. This will remain the process group of which your shell is a member, so your shell will remain in the foreground.

如果一个后台进程组试图从终端读取,它会发出信号,停止它。输出到终端仍然是允许的 - 这是正常的(尝试 LS&安培; 在常规的shell)。为了实现在你的shell的 FG 命令,你需要在 tcsetpgrp()函数改变前台进程组。

If a background process group tries to read from the terminal, it will be sent a signal to stop it. Output to the terminal is still allowed - this is normal (try ls & in your regular shell). To implement the fg command in your shell, you will need the tcsetpgrp() function to change the foreground process group.

您也想叫 waitpid函数() WNOHANG 选项定期 - 比如,你立即显示前shell提示符。这将允许您检测时,后台进程已退出或停止(或者,您可以处理 SIGCHLD 信号)。

You will also want to call waitpid() with the WNOHANG option regularly - say, immediately before you display the shell prompt. This will allow you to detect when the background process has exited or stopped (or alternatively, you can handle the SIGCHLD signal).

这篇关于关于用fork()在我的虚拟外壳后台进程和子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆