[英]Unix system calls : read/write and the buffer
I am writing a pretty simple script.我正在编写一个非常简单的脚本。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
int pipefd[2];
pid_t c;
int value[2];
c = fork();
if(c<0){
perror("in fork");
exit(1);
}
if(c==0){
printf("i am the child\n");
int buf[2];
buf[0]=3;
buf[1]=0;
write(pipefd[1], buf, 4);
write(pipefd[1],buf+1,4);
close(pipefd[1]);
exit(0);
}
if (pipe(pipefd) == -1) { /*UPDATE */
perror("pipe");
exit(EXIT_FAILURE);
}
read(pipefd[0], value, 4);
read(pipefd[0], value+1, 4);
close(pipefd[0]);
printf("%d %d\n", value[0], value[1]);
exit(0);
}
What I intend to do is to achieve:我打算做的是实现:
value[0] = buf[0];值[0] = buf[0]; value[1] = buf[1];
值[1] = buf[1];
( and print those of course). (当然打印出来)。
But all I get as a result is:但我得到的结果是:
-1299582208 32766
i am the child
Because, I have ints, I assumed that each will hold 4 bytes.因为,我有整数,我假设每个整数都包含 4 个字节。 And I think that for an int array each element will holds 4 bytes.
而且我认为对于一个 int 数组,每个元素将包含 4 个字节。 But clearly I am missing something.
但显然我错过了一些东西。 Any help?
有什么帮助吗?
As I mentioned in my top comment: Where is the pipe
syscall?正如我在顶级评论中提到的:
pipe
系统调用在哪里?
Without it, the write
and read
calls will probably fail because pipefd
has random values.没有它,
write
和read
调用可能会失败,因为pipefd
具有随机值。
So, the parent will never have value
filled in correctly.因此,父母永远不会正确填写
value
。
Because these [unitialized] values are on the stack, they will have random values, which is what you're seeing.因为这些 [未初始化] 值在堆栈上,它们将具有随机值,这就是您所看到的。
This is UB [undefined behavior].这是 UB [未定义行为]。
Different systems/compilers may manipulate the stack differently, which is why you see different [yet still random] results on different configurations.不同的系统/编译器可能会以不同的方式操作堆栈,这就是为什么您会在不同的配置上看到不同的[但仍然是随机的] 结果。
To fix, add the following above your fork
call:要修复,请在您的
fork
调用上方添加以下内容:
pipe(pipefd);
I downloaded, built, and ran your program.我下载、构建并运行了你的程序。 Before I added the fix, I got random values.
在我添加修复之前,我得到了随机值。 After applying the fix, I get
3 0
as the output, which is what you expected/wanted.应用修复后,我得到
3 0
作为 output,这是您所期望/想要的。
Note: As others have mentioned, you could check the return codes for read
and write
.注意:正如其他人所提到的,您可以检查
read
和write
的返回码。 If you had, they might return -1
and put an error code in errno
that would have helped you debug the issue.如果你有,他们可能会返回
-1
并在errno
中放置一个错误代码,这将有助于你调试问题。
A very simple fix would be to put a sleep(1)
call right above your read()
calls - obviously this isn't a great solution.一个非常简单的解决方法是在您的
read()
调用之上放置一个sleep(1)
调用 - 显然这不是一个很好的解决方案。
An important early lesson in multi process programming and communications is "race conditions".多进程编程和通信的一个重要早期教训是“竞争条件”。 Your fork'd child is executing before the parent, it seems.
看来,您的分叉子项在父项之前执行。 I bet if you ran this 20 times, you might get X number of times where it does what you want!
我敢打赌,如果你跑了 20 次,你可能会得到 X 次它做你想做的事!
You cannot guarantee the order of execution.您不能保证执行的顺序。 So a sleep(1) will suffice until you learn more advanced techniques on resource locking (mutexes, semaphores).
因此,在您学习更高级的资源锁定技术(互斥锁、信号量)之前,sleep(1) 就足够了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.