我编写了一个程序,它首先复制当前进程(使用App
),然后使用using Xamarin.Forms;
namespace PersistWebViewSample
{
public class StartPage : ContentPage
{
public StartPage()
{
var navigateToWebViewButton = new Button
{
Text = "Open Persistent Web View"
};
navigateToWebViewButton.Clicked += async (sender, e) => await Navigation.PushAsync(App.PersistentWebView);
Title = "Start";
Content = navigateToWebViewButton;
}
}
public class App : Application
{
static readonly string xamarinUrl = "https://www.xamarin.com/";
public App()
{
MainPage = new NavigationPage(new StartPage());
}
public static ContentPage PersistentWebView { get; } = new ContentPage
{
Title = "Persistent Web View",
Content = new WebView
{
Source = xamarinUrl
}
};
}
}
创建子进程。
现在的问题是子进程无法接受任何输入。
fork()
计划:
execl()
我使用命令child.c
编译我的child.c以生成名称为#include<stdio.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
int p, pp;
int a;
char dummy;
printf("\n enter value of a \n");
//fflush(0); // was using to clean STDIN, STDOUT
//fflush(1);
scanf("%c",&dummy); // simply using to accept any new line character if present any.
scanf("%c",&dummy); // simply using to accept any new line character if present any.
scanf("%d",&a);
p = getpid();
pp = getppid();
printf("\nI m child with pid %d and ppid %d \n", p, pp);
char *msg = argv[1];
printf("\n Message from parent is %s \n",msg);
printf("\n The value of a is %d ",a);
return 0;
}
的目标文件,我在gcc child.c -o child
文件中使用该文件
我的child
计划:
parent.c
我尝试在孤儿状态和僵尸状态下运行程序,但在这两种情况下,子进程都没有接受输入。
当我运行父程序的./a.out时,我得到以下输出:
我是父母的pid 6801和ppid 4136
再见[aupadhyay @ localhost practice] $输入一个
的值我是pid 6802和ppid 1的孩子
来自父母的消息是你好
a的值为0
控制台不接受任何输入,而是打印默认值a。
有关如何在子进程中获得输入的任何信息/帮助将不胜感激。
答案 0 :(得分:2)
注意:根据@Gilles的编辑和评论,答案得到了彻底改革。
虽然我可以复制您描述的行为,但我也可以通过I / O重定向向孩子提供输入:
./parent <<EOF
12345
EOF
...导致:
我是父母的pid 4430和ppid 2515
再见
$
输入
的值我是pid 4431和ppid 1的孩子
来自父母的消息是你好
a的值是12345
请注意,重定向到父标准输入的数据已成功读取并由孩子回显,因此问题不在于孩子无法接受输入。在某些情况下,它不等待或成功读取输入,而是继续读取尝试,只能通过在这些条件下失败的scanf()
调用来解释。
对此类失败的最合理的解释是,在尝试读取时,进程组已移至后台。通常,尝试从其控制终端读取的后台进程将导致其整个进程组停止(不终止)。但是,在您的情况下,进程组是孤立:组中没有进程在会话内但在组外部有父进程。在本案例和其他一些特殊情况下,来自其控制终端的后台流程read()
,例如scanf()
来电are required to fail, setting errno
to EIO
下的scanf
。
在该事件中,EOF
反过来返回errno
以指示错误,将EIO
设置为scanf
。测试perror
的返回值并调用wait()
来观察此情况。读取失败是一种明智的行为,因为它们有助于孤立组中的进程运行到完成和终止,而不是挂起,或者操作系统会立即杀死它们。 POSIX的目标似乎是为通过终止作为作业控制shell的父级而孤立的进程组提供优雅的处理,不让任何进程重新启动进程组。
你的情况并非如此,POSIX似乎意图迎合,但规范也支持观察到的行为:当其领导者死亡时,shell将前台进程组转移到后台,但(似乎)没有将其置于工作之下控制作为后台作业。据我所知,POSIX没有强制shell表现出这样的行为,但它也不需要。结果是一个孤立的进程组,其情况类似于POSIX构思的那些,同样也受到孤立进程组的特殊规定的支持。
如果您希望孩子保留对父母控制终端的完全访问权限,那么您应确保父母在孩子出生之前不会终止。如果父母在此期间没有其他任何事情要做,那么确保孩子首先终止的适当方式是父母waitpid()
或#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int p, pp;
p = getpid();
pp = getppid();
printf("\nI m parent with pid %d and ppid %d \n", p, pp);
int b = fork();
if (b == 0)
{
execl("./child", "child", "hello", 0);
}
else
{
printf("\nBye\n");
wait(NULL);
}
return 0;
}
:
order_by