我正在阅读一本在线书籍,以更好地了解操作系统是如何工作的,下面是它的示例代码:
操作系统:三种简单的方法
在它的介绍部分,第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的行为。