双&号在此程序中起什么作用?
我正在学习如何使用 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;
}
那么,双 & 符号到底有什么用呢? 我用“printf”运行程序来了解这些值到底是什么,但它变得更加混乱,因为第一个“printf”中的输出是 0,第二个“printf”中的输出是“1”。所以我不太确定双&符号在做什么。
我很感激你的帮助!
I am learning how to create processes by using fork, and I am confused in the following. This is the code:
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;
}
So, what is the use of double ampersand exactly doing?
I ran the program with a "printf" to know what was exactly the values, but it became more confusing because the output in the first "printf" is 0 and the second "printf" is "1". So I am not quite sure what is double ampersand doing.
I appreciate the help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
它称为逻辑 AND 运算符。这将评估两个操作数的逻辑与结果。该运算符的属性是:
首先计算左侧操作数,如果它为 TRUE(非零),则计算右侧操作数。如果它也为真,则整个表达式为真,否则为假。另一方面,如果左侧操作数为 FALSE,则右侧操作数根本不会被求值。之所以能做到这一点,是因为当其中一个操作数为假时,无论另一个操作数是什么,表达式都会变为假。这在您的代码中称为短路
,如果左手 if
ret
是true,则仅计算右侧部分,最终调用 fork () 系统调用。调用的返回值与 ret 的当前值进行 AND 运算,并重新分配给 ret。基本上它的工作原理
如下:
考虑下面的叉树。每个树“节点”显示每个单独语句中执行语句的顺序。一条线完成一项工作。
这是每个过程中发生的事情。
p1
执行
fork()
一次,并在ret中有一个pid(非零)。打印pid
短路允许执行fork()。由于这是父级,它返回另一个 pid,该 pid 与前一个子 pid 进行“与”运算,结果为 1。因此 ret 现在包含 1,该值在第二个 printf 中打印。由于
ret
为1,if
不执行。打印出“你好”。p2
p1 的子级,因此 ret 为 0。在第一个 printf 中打印 0。短路不允许
fork()
调用。if
主体被输入,并且fork()
被调用,这使得(p4)。现在 (p2) 继续打印 Hello。p3
p1的孩子,所以
fork()
返回是0,与ret进行AND运算,赋值后变为0。这是在第一个 printf 之后生成的,因此只有第二个 printf 显示 0。输入
if
,执行fork()
,生成(p5)。现在 p4 继续打印 Hello。p4
从
if
主体开始,退出并打印 Hellop5
从
if
主体开始,退出并打印 Hello上面我试图表达进程生成树,每个进程中的工作顺序由树上进程“节点”的每一行表示。边表示spawn,边从相应的分叉处开始。
It is called the logical AND operator. This will evaluate the logical ANDing result of the two operands. The property of this operator is:
First the left hand side operand is evaluated, if it is TRUE (non zero), then the right hand side operand is evaluated. If it is also true then the whole expression is true, or false otherwise. On the other hand, if the left hand side operand is FALSE, then the right hand side operand is not evaluated at all. This can be done because, as one of the operands is false, whatever be the other operand, the expression becomes false. This is known as short circuiting
In your code, if the left hand if
ret
is true, then only the right hand side portion is evaluated, which eventually calls thefork ()
system call. The return value of the call is ANDed with the current value ofret
, and reassigned toret
.Basically it works like
Read this:
Consider the fork tree below. Each tree "node" shows the sequence of executed statement in each individual statement. One work in one line.
Here what goes in each process.
p1
executes
fork ()
once, and has a pid (non-zero) in ret.prints the pid
short circuit allows to execute fork (). As this is the parent, it returns another pid, which is anded with the previous child pid, which evaluates to 1. Therefore
ret
now contains 1, which is printed in the second printf. asret
is 1,if
is not executes. Hello is printed.p2
Child of p1, so ret has 0. prints 0 in the first printf. Short circuit does not allow
fork ()
call.if
body is entered, andfork ()
is called, which makes (p4). Now (p2) proceeds to print Hello.p3
Child of p1, so
fork ()
return is 0, which is ANDed with ret, and makes it 0 after the assignment. This is spawned after the first printf, so only the second printf shows 0.if
is entered,fork ()
is executed, which makes (p5). Now p4 proceeds to print Hello.p4
starts from
if
body, gets out and prints Hellop5
starts from
if
body, gets out and prints HelloAbove I have tried to express the process spawn tree, and the sequence of works in each process is expressed in each line of the process "node" on the tree. The edges denote spawn, and the edge start at the corresponding fork.
在 C 语言中,双与号
&&
是短路逻辑 AND 运算。如果你有类似a && b
,则计算结果如下:如果a
和b
都为 true,则返回 true,但如果a
为 true,则返回 true false 则b
将永远不会被执行。作为添加的示例:
因此,如果
ret
为 true,您的代码仅调用fork()
。然后将ret
指定为 0(ret
为 0)或 1(ret
和fork()
均为 true )。In C, the double ampersand
&&
is a short-circuit logical AND operation. If you have something likea && b
, then this will evaluate as follows: it will return true if botha
andb
are true, but ifa
is false thenb
will never be executed.As an added example:
So your code only calls
fork()
ifret
is true.ret
is then assigned either 0 (ret
is 0) or 1 (bothret
andfork()
are true).它是一个逻辑 AND,意味着如果
ret
为 true(非零),并且fork()
的结果为 true(非零),则将 true 分配给ret
,否则将 false(零)分配给ret
。由于此运算符是短路,
fork()
将仅当 ret 为 true 时才被调用。It's a logical AND, meaning if
ret
is true (non-zero), AND the result offork()
is true (non-zero) assign true toret
, else assign false (zero) toret
.Since this operator is short-cirucuited,
fork()
will be called only ifret
is true.我认为问题在于对 fork() 工作原理的误解。如果你使用的是 UNIX,你需要执行“man fork”,因为根据我读到的:
并且..
我怀疑可能发生的情况是,您可能会看到多个分叉进程的输出,这只会让您感到困惑。您的程序的确切完整输出是什么?
这不太可能是短路问题,因为即使第二个失败,至少第一个 fork 应该成功,因此如果该 fork 成功,您应该从至少一个第一个 printfs 获得 pid。
I think what's wrong is a misunderstanding of how fork() works. If you're on UNIX, you need to do "man fork", because according to the one I read:
and..
I suspect what might be happening is you might be seeing output from multiple forked processes that is only succeeding in confusing you. What is the exact full output of your program?
This is unlikely to be a short circuit problem because even if the second one fails, at least the first fork should have succeeded, and thus you should get a pid from at least one of the first printfs if that fork succeeded.
这是一个惰性逻辑
AND
函数。如果您需要更多信息,请搜索AND
的真值表。它是惰性的,因为如果 ret 为 false,则不会评估fork()
,因为与false
进行 AND 运算的任何内容始终为false
。It's a lazy logical
AND
function. Search for the truth table forAND
if you need more info on that. It's lazy because if ret is false,fork()
will not be evaluated since anything ANDed withfalse
is alwaysfalse
.这是一个短路逻辑与。如果
ret
为0,那么它将执行fork()
。如果没有,就不会。我可以为您演示一下代码。所以我们有第一个进程,进程 1 执行此代码。让我们假设所有分叉都成功(但您应该确保检查这一点...我认为它应该在现有代码中处理,但并不那么明显)。
It's a short-circuit logical AND. If
ret
is 0, then it will execute thefork()
. If not, it won't. I can walk through the code for you.So we have our first process, process 1 executing this code. Let's assume all forks are successful (but you should make sure to check this... I think it should be handled within the existing code but it isn't that obvious).
第一个分叉 ret - fork() 将导致 3 种可能的结果:
第二个 fork,ret = ret && fork(),仅当 ret 非零时才会执行 fork()。这可能发生在父级良好情况和父级错误情况中。该语句的结果可以是:
第三个 fork if (ret == 0) { fork() } 仅当 ret 为零时才会执行。
那么这一切意味着什么呢?第二个分叉似乎很可疑,因为在父级成功或失败的情况下,第一个分叉的返回值可能不为零!我不知道这是否是预期的结果,但似乎值得怀疑。
如果第一个分叉返回在子级中,则第三个分叉将会发生,第二个分叉不会被执行,但第三个分叉会执行。如果第一个 fork 在父上下文中并且第二个 fork 在子上下文中,则第三个 fork 也可以被执行。
有人检查这个逻辑,因为我永远不会写这种代码。
The first fork, ret - fork(), will result in 3 possible outcomes:
The second fork, ret = ret && fork(), will execute the fork() only if ret is nonzero. This can happen in the parent good case and the parent error case. The result of this statement can be:
The third fork, if (ret == 0) { fork() }, will only execute if ret is zero.
So what does all of this mean? The second fork seems suspect in that the return value from the first fork could be nonzero in the case of a parent success or failure! I don't know if this was the intended result, but it seems dubious.
The third fork would happen if the first fork return was in the child, the second fork doesn't get executed, but the third does. The third fork can also get executed if the first fork is in the parent context and the second fork is in the child context.
Someone check this logic as I could never write this kind of code.
在C语言中,
&&
运算符的作用是这样的:函数
fork
返回 0 给子进程,另一个数字(子进程的 pid)返回给父进程,所以在你的第一个之后fork
,在父进程中ret>0
,在子进程中,ret==0
。如果取消第一个printf
的注释,您将得到 0 和另一个数字。然后,你运行你的线路。在子进程中,
ret
为0,因此&&
的计算在fork之前停止,ret
仍为0。在父亲中,ret>0
,因此它运行fork()
,并创建另一个孩子。在父进程中,fork
返回正数,因此ret
将为1,而在第二个子进程中,fork
返回0,因此>ret
将为 0。因此,如果您仅取消注释第二个
printf
,您将得到0
,0
,1
(也许在不同的命令)。然后,执行
if (ret==0) fork();
,这样两个子进程(其ret
为 0)都会创建新进程。现在,您总共有 5 个进程,因此Hello world\n
行将被打印 5 次。(在搞乱
fork
的同时使用输出函数是相当危险的 - 您有 5 个进程在没有任何锁定的情况下写入同一文件,因此您可以获得类似HHHHHeeeeellllllllooooo wwwwwooooorrrrrlllllddddd\n\n\ 的结果n\n\n
)In C language, the act of the
&&
operator is so:The function
fork
return 0 to the child process, and another number (the child's pid) to the father, so after your firstfork
, in the father processret>0
, and in the child process,ret==0
. If you uncomment the firstprintf
, you will get 0 and another number.Then, you run your line. In the child,
ret
is 0, so the calculating of the&&
is stopped before of the fork, andret
remains 0. In the father,ret>0
, so it runsfork()
, and create another child. In the father process,fork
return positive number, soret
will be 1, and in the second child,fork
return 0, soret
will be 0.So, if you uncomment only the second
printf
, you will get0
,0
,1
(Maybe in different order).Then, you do
if (ret==0) fork();
, so the both children (whoseret
is 0) create new process each. Now, you have totally 5 processes, so the lineHello world\n
will be printed 5 times.(It's pretty dangerous to use output functions while messing with
fork
- you have 5 processes that write to the same file without any locking, so you can get results likeHHHHHeeeeellllllllllooooo wwwwwooooorrrrrlllllddddd\n\n\n\n\n
)