Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 能否确定fork()的执行顺序?_C_Fork_Scheduling - Fatal编程技术网

C 能否确定fork()的执行顺序?

C 能否确定fork()的执行顺序?,c,fork,scheduling,C,Fork,Scheduling,我正在编写教科书“第7版操作系统概念”的一个练习,我对fork()的工作原理有点困惑。据我所知,fork()创建了一个子进程,它与其父进程同时运行。但是,我们如何确切地知道哪个进程首先运行?我指的是执行命令 问题 使用在子进程中生成斐波那契序列的fork()系统调用编写一个C程序。序列号将在命令行中提供 这是我的解决方案: #include <sys/types.h> #include <stdlib.h> #include <stdio.h> #includ

我正在编写教科书“第7版操作系统概念”的一个练习,我对
fork()
的工作原理有点困惑。据我所知,
fork()
创建了一个子进程,它与其父进程同时运行。但是,我们如何确切地知道哪个进程首先运行?我指的是执行命令

问题
使用在子进程中生成斐波那契序列的
fork()
系统调用编写一个C程序。序列号将在命令行中提供

这是我的解决方案:

#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

void display_fibonacci_sequence( int n ) {
    int i = 0;
    int a = 1;
    int b = 1;
    int value;
    printf( "%d, %d, ", a, b );
    for( ;i < n - 2; ++i ) {
        value = a + b;
        printf( "%d, ", value );
        a = b;
        b = value;
    }
    printf( "\n" );
}

int main( int argc, char** argv ) {
    int n;
    pid_t pid;
    pid = fork();
    if( argc != 2 ) {
        fprintf( stderr, "Invalid arguments" );
        exit( -1 );
    }
    n = atoi( argv[1] );

    if( pid < 0 ) {
        fprintf( stderr, "Fork failed" );
        exit( -1 );
    }
    else if( pid == 0 ) {
        display_fibonacci_sequence( n );
    }
    else { // parent process
        // what do we need to do here? 
    }
}
#包括
#包括
#包括
#包括
无效显示\u斐波那契\u序列(int n){
int i=0;
INTA=1;
int b=1;
int值;
printf(“%d,%d,”,a,b);
对于(;i

老实说,我看不出使用
fork
和不使用
fork
之间有什么区别。此外,如果我想让父进程处理来自用户的输入,让子进程处理显示,我该怎么做呢?

你问了很多问题,我将尝试以方便的顺序回答它们

第一个问题 老实说,我看不出使用fork和不使用fork有什么区别 用叉子

那是因为这个例子不是很好。在您的示例中,父对象不做任何事情,因此fork是无用的

第二 您需要等待孩子终止。一定要仔细阅读那一页

第三 我希望父进程处理来自用户的输入,并让 子进程处理显示

读取拨叉前的输入,并在
if(pid==0)

第四 但是,我们如何确切地知道哪个进程首先运行

很少有项目会关注这一点。您无法知道执行顺序,它完全取决于环境。TLPI说:

在fork()之后,不确定是父进程还是子进程 下一个孩子可以访问CPU。在多处理器系统上,它们可以同时访问CPU

隐式或显式依赖于特定 实现正确结果的执行顺序对 由于竞赛条件而导致的失败


也就是说,操作系统可以允许您控制此顺序。例如,Linux有
/proc/sys/kernel/sched\u child\u首先运行

系统调度器选择运行的进程,这与操作系统上运行的任何其他应用程序都不一样。生成的进程被视为调度程序在队列中分配优先级或位置的任何其他进程或任何实现。

我们不知道先运行的是父进程还是子进程。这就是为什么父进程通常必须等待子进程完成,如果它们之间存在对执行顺序的依赖关系

在您的特定问题中,没有任何特定的理由使用
fork()
。你的教授给你这个可能只是为了一个小例子

如果希望父级处理输入,子级处理计算,则只需将调用移动到处理命令行参数的点下方的
fork()
。使用与上面相同的基本逻辑,让子调用
显示fibonacci\u序列
,让父调用等待

但是,我们如何确切地知道哪个进程首先运行?我是说 执行命令

没有人能保证谁先跑
fork
如果是子对象,则返回
0
;如果是父对象,则返回子对象的
pid
。理论上,它们可以在多处理器系统上同时运行。如果您确实想确定哪个先运行,那么可以在两个进程之间拥有一个共享锁。首先获得锁的可以说是先运行的

在你的else声明中,关于做什么。您需要使用
wait
waitpid
等待子进程退出

老实说,我看不出使用
fork
和不使用
fork
之间有什么区别

区别在于您创建了一个子进程。系统上的另一个进程正在进行计算。对于这个简单的问题,最终用户体验是相同的。但是当您编写像服务器这样需要同时处理事务的系统时,
fork
是非常不同的

此外,如果我希望父进程处理来自用户的输入,并让子进程处理显示,我该怎么做


您似乎已经有了该设置。父进程只需要等待子进程完成。子进程将
将结果打印到终端。父进程当前从命令行获取用户输入。

虽然您无法控制哪个进程(父进程或子进程)在
fork
之后首先调度(事实上,在SMP/multicore上,它可能是两者都!),但有许多方法可以同步这两个进程,一方等待另一方到达某一点,然后再执行任何非平凡的操作。一种经典的、非常便携的方法如下:

  • fork之前
    
    else {
        // what do we need to do here? 
    }