Naw*_*sef 0 c linux parent-child
我试图使用管道读取从子进程发送到父进程的消息.我在这里问了问题并得到了一些帮助,我得到了消息.但问题是消息一次显示一个字符.我不知道为什么.这是我的代码:
int main(int argc, char *argv[]){
printf("\nWritten by Nawar Youssef\n");
int i, x, fd_log[2], fd_A_B[2], pipe_size=500;
char ch, message_from_A[pipe_size], message_from_B[pipe_size],
msg_to_log[pipe_size], msg_to_B[pipe_size];
pipe(fd_log);
pipe(fd_A_B);
//fork process A
if (fork()==0) { //child
printf("Inside process A\n");
for (i=0; i < 10; i++) {
//creat new a record (C or D 0 to/or 9)
x = (rand() % 2);
if (x == 1)
ch='C';
else
ch='D';
//write msg to log pipe
sprintf(msg_to_log, "A sent to B: %c %d\n", ch, i);
printf("wirtten to log pipe--> %s\n", msg_to_log);
close(fd_log[READ]);
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
}//end for()
close(fd_log[WRITE]);
_exit(1); //process A
}
else { //parent
close(fd_log[WRITE]);
while (read(fd_log[READ], message_from_A, strlen(msg_to_log)+1) > 0 ) {
sleep(1);
printf("\nIn log: msg from A: %s", message_from_A);
}
close(fd_log[READ]); //this line won't affect output
}
}
Run Code Online (Sandbox Code Playgroud)
如下所示的输出,如果你注意到,字符就是形成句子:A发送到B:C 0,这是想要的输出,但每个字符显示在它自己的行上!
在日志中:来自A:Aь的消息|?
在日志中:来自A:ь的消息|?
在日志中:来自A:sь|?的消息
在日志中:来自A:eь|?的消息
在日志中:来自A:ms的msg |?
在日志中:来自A:tь|的msg?
在日志中:来自A:ь的消息|?
在日志中:来自A:tь|的msg?
在日志中:来自A:oь|的msg?
在日志中:来自A:ь的消息|?
在日志中:来自A:Bь的消息|?
在日志中:来自A :: ms的消息|?
在日志中:来自A:ь的消息|?
在日志中:来自A:Cь的消息|?
在日志中:来自A:ь的消息|?
在log:msg中来自A:0ь|?
读取代码使用:
read(fd_log[READ], message_from_A, strlen(msg_to_log)+1)
Run Code Online (Sandbox Code Playgroud)
在父级中,你没有初始化,msg_to_log所以你可能得到0作为字符串长度(大多数是偶然的;当然不是设计),并且一次读取一个字符.不要strlen()在接收代码中使用; 使用sizeof()- 没有+1!
我试过使用
sizeof()但它只给了我第一条消息,所以输出是:Run Code Online (Sandbox Code Playgroud)In log: msg from A: A sent to B: C 0然后程序终止了
像这样?
$ ./piperead
Inside process A
written to log pipe--> A sent to B: C 0
written to log pipe--> A sent to B: D 1
written to log pipe--> A sent to B: C 2
written to log pipe--> A sent to B: C 3
written to log pipe--> A sent to B: C 4
written to log pipe--> A sent to B: C 5
written to log pipe--> A sent to B: D 6
written to log pipe--> A sent to B: D 7
written to log pipe--> A sent to B: C 8
written to log pipe--> A sent to B: C 9
In log: msg from A: [[A sent to B: C 0
]]
In log: msg from A: [[A sent to B: C 8
]]
$
Run Code Online (Sandbox Code Playgroud)
除此之外有两个读取,一个用于条目0..7,一个用于条目8..9.
这是来自您的代码的温和修改版本.问题是您在管道上写入空字节,并且read()在单个操作中读取多个消息,但是printf()在第一个空字节处停止.
以下是代码的改编版本的输出:
$ ./piperead
Inside process A
0: written to log pipe--> [[A sent to B: C 0]]
1: written to log pipe--> [[A sent to B: D 1]]
2: written to log pipe--> [[A sent to B: C 2]]
3: written to log pipe--> [[A sent to B: C 3]]
4: written to log pipe--> [[A sent to B: C 4]]
5: written to log pipe--> [[A sent to B: C 5]]
6: written to log pipe--> [[A sent to B: D 6]]
7: written to log pipe--> [[A sent to B: D 7]]
8: written to log pipe--> [[A sent to B: C 8]]
9: written to log pipe--> [[A sent to B: C 9]]
In log: msg from A: 85: 16: [[A sent to B: C 0]]
In log: msg from A: 85: 16: [[A sent to B: C 5]]
$
Run Code Online (Sandbox Code Playgroud)
请注意,读取操作都获得了85个字节的数据,但只有前16个(17个)可见为打印的字符串printf().管道中数据的划分取决于很多因素.这是在具有6个CPU的机器上运行的.我运行了其他时间,并在一次操作中读取了所有170个字节; 我也得到了119:51的分割,以及136:34(这是第一个例子中显示的内容),并且任何其他n*17:(10-n)*17的比例也是可能的.
这是修改后的来源:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
enum { READ = 0, WRITE = 1 };
int main(void)
{
int i;
int x;
int fd_log[2];
int pipe_size = 500;
char ch;
char message_from_A[pipe_size];
char msg_to_log[pipe_size];
pipe(fd_log);
if (fork() == 0) // child
{
printf("Inside process A\n");
for (i = 0; i < 10; i++)
{
// creat new a record (C or D 0 to/or 9)
x = (rand() % 2);
if (x == 1)
ch = 'C';
else
ch = 'D';
// write msg to log pipe
sprintf(msg_to_log, "A sent to B: %c %d", ch, i);
printf("%d: written to log pipe--> [[%s]]\n", i, msg_to_log);
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log) + 1);
} // end for()
close(fd_log[READ]);
close(fd_log[WRITE]);
_exit(1); // process A
}
else // parent
{
int nbytes;
close(fd_log[WRITE]);
while ((nbytes = read(fd_log[READ], message_from_A, sizeof(message_from_A))) > 0)
{
printf("In log: msg from A: %d: %zu: [[%s]]\n", nbytes, strlen(message_from_A),
message_from_A);
sleep(1);
}
close(fd_log[READ]); // this line won't affect output
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
修改打印代码以打印缓冲区中的所有字符串并不难 - 有点繁琐,但对您来说有利于处理.
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |