双安培在这个程序中做了什么?

Osc*_*rin 1 c fork process ampersand

我正在学习如何使用fork创建进程,我对以下内容感到困惑.这是代码:

int main() {
    int ret = fork();
    // printf("%d\n", ret);
    ret = ret && fork(); /* Here is where I am confused*/
    // print("ret: %d\n", ret);
    if(ret == 0) {
        fork();
    }
    printf("Hello world\n");
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

那么,双安瓿的用途是什么呢?我使用"printf"运行程序以了解究竟是什么值,但它变得更加混乱,因为第一个"printf"中的输出为0而第二个"printf"为"1".所以我不太确定双安瓿是做什么的.

我很感激帮助!

sim*_*ona 6

在C中,双和号&&是短路逻辑AND操作.如果你有这样的事情a && b,那么这将评估如下:它会返回,如果双方真的ab是真实的,但如果a是假,则b不会被执行.

作为一个例子:

int a = 0;
if (a && myfunc(b)) {
    do_something();
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,短路评估保证永远不会调用myfunc(b).这是因为评估为false.此功能允许两个有用的编程结构.首先,如果第一个子表达式检查是否需要昂贵的计算并且检查评估为假,则可以消除第二个参数中的昂贵计算.其次,它允许一个构造,其中第一个表达式保证条件,否则第二个表达式可能导致运行时错误.

所以你的代码只调用fork()if ret是真的.ret然后分配0(ret0)或1(两者retfork()为真).


pho*_*xis 6

它被称为逻辑AND运算符.这将评估两个操作数的逻辑ANDing结果.该运营商的财产是:

首先评估左侧操作数,如果它是TRUE(非零),则评估右侧操作数.如果它也是真的则整个表达式为真,否则为假.另一方面,如果左侧操作数为FALSE,则根本不评估右侧操作数.这样做是因为,由于其中一个操作数是假的,无论是哪个操作数,表达式都会变为false.这被称为短路

在你的代码中,如果左手if ret为真,那么只评估右手边部分,最终调用fork ()系统调用.调用的返回值与当前值进行AND运算ret,并重新分配给ret.

基本上它的工作原理就像

if (ret == TRUE)
{
  retval = fork ();
  ret = ret && retval;
}
Run Code Online (Sandbox Code Playgroud)

读这个:

成功时,子进程的PID在父进程中返回,并在子进程中返回0.失败时,在父项中返回-1,不创建子进程,并正确设置errno.

考虑下面的叉树.每个树"节点"显示每个单独语句中执行语句的顺序.一行一件.

    (p1)
+--+ret = fork ();
|   printf 1 shows pid
|   && allows         fork (), ret = 1 = pid1 && pid2 
|   printf 2 shows 1    +
|   `if' not entered    |
|   show hello          |
|                       |    (p3)
|                       +--+ ret = 0 = ret && fork () (this is 0 here)
+-----+                      printf 2 shows 0
      |                      `if' is entered
      |                      fork ()
      |                      show hello
      |                            +
      |                            |
      +                            |
     (p2)                          |
    level 1                        +-------+
    print 0 in 1st printf                  |
    && DOES NOT allow fork ()            (p5)
    print 0 in 2st printf             show hello
   `if' entered
    fork () +-----------+
    show hello          |
                        |
                        +
                      (p4)
                    show hello
Run Code Online (Sandbox Code Playgroud)

这是每个过程的内容.

p1 执行fork ()一次,并且在ret中有一个pid(非零).打印pid短路允许执行fork().由于这是父节点,它返回另一个pid,它与前一个子节点pid一起计算,其值为1.因此ret现在包含1,它在第二个printf中打印.因为ret是1,if不执行.你好打印.

p2 p1的子项,因此ret在第一个printf中打印0.短路不允许fork ()通话.if身体进入,并被fork ()调用,这使(p4).现在(p2)继续打印Hello.

p3 p1的子项,因此fork ()return为0,与ret进行AND运算,并在赋值后使其为0.这是第一个printf后产生了,所以只有第二个printf显示为0 if被输入,fork ()则执行,这使得(P5).现在p4继续打印Hello.

p4ifbody 开始,出去打印Hello

p5ifbody 开始,出去打印Hello

上面我试图表达过程产生树,并且每个过程中的工作序列在树上的过程"节点"的每一行中表示.边缘表示spawn,边缘从相应的fork开始.