你能解释一下为什么.net控制台应用程序在后台模式下的工作方式与C控制台应用程序不同吗?



我正在阅读一本在线书籍,以更好地了解操作系统是如何工作的,下面是它的示例代码:

操作系统:三种简单的方法

在它的介绍部分,第3页

我在cpu.c文件中找到了这样的C代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <assert.h>
#include "common.h"
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "usage: cpu <string>n");
exit(1);
}
char *str = argv[1];
while (1) {
Spin(1);
printf("%sn", str);
}
return 0;
}

书像这样编译文件:

prompt> gcc -o cpu cpu.c -Wall

我,作为一个c#用户,将其转换为一个dotnet 6控制台应用程序的等效c#代码(在顶级语句中):

var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
while (await timer.WaitForNextTickAsync())
{
if (args.Length == 0)
{
Console.WriteLine("No Arguments");
break;
}
Console.WriteLine(args[0]);
}

这段代码显示了与book单独执行时完全相同的结果。但是,当执行多个后台任务时,问题就出现了。

图书执行:

prompt> ./cpu A & ./cpu B & ./cpu C & ./cpu D &

及其结果:

[1] 7353
[2] 7354
[3] 7355
[4] 7356
A
B
D
C
A
B
D
C
A
...

我在Windows电脑的Powershell 7中执行了相同的shell命令:

prompt> .CPU.exe A & .CPU.exe B &

但结果是这样的;

Id     Name            PSJobTypeName   State         HasMoreData     Location    Command
--     ----            -------------   -----         -----------     --------    -------
1      Job1            BackgroundJob   Running       True            localhost   Shell.Man…
3      Job3            BackgroundJob   Running       True            localhost   Shell.Man…

PowerShell根本不会打印后台作业中的任何字符。

谁能解释一下为什么我得到了这个结果,如果可能的话,我该如何修复它,以便我能得到与书相同的结果?

在表面上,Powershell &操作符看起来类似于posix壳&操作符。以相同的目标设计。

当posix shell进程使用fork()exec()生成子进程时,所有打开的文件句柄将被共享。除非您显式指定如何重定向或管道输出。

Powershell作业的标准输出被重定向到一个新的管道,所以你可以决定何时读取每个作业的输出。

windows操作系统具有与posix c相同的行为,但是CMD.exe&操作符是一个顺序操作。相当于正的;。我找不到具有相同后台作业行为的操作的引用。

如果您希望在每个操作系统上重复相同的示例,可以安装bash shell。

或者当你传入多个参数时,你可以通过将c#控制台程序更改为Process.Start()本身作为子进程来模拟shell的行为。

相关内容

  • 没有找到相关文章

最新更新