我希望父进程和子进程使用管道在C linux中进行通信。首先,我希望父传递一个字符串,然后让孩子确认它。我创建了两个文件描述符。一个用于父母对孩子,即readpipe和其他writepipe for viceversa。问题是它没有把我的数据作为输入。另外,我希望printf语句如“输入你的数据”一次打印,但是因为在fork之后,有两个进程,所以它们被显示两次。任何替代方案??
//readpipe[0] = child read
//readpipe[1]= parent write
//writepipe[0]=parent read
//writepipe[1]=child write
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
pid_t pid;
int r;
/* Hope this is big enough. */
char buf[1024];
char cp[50];
char ans;
int readpipe[2];
int writepipe[2];
int a;
int b;
a=pipe(readpipe);
b=pipe(writepipe);
if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }
printf("\nSEND SOMETHING TO CHILD PROCESS\t");
scanf(" %c",&ans);
pid=fork();
if(pid==-1)
{
printf("pid:main");
exit(1);
}
while(ans=='y' || ans=='Y')
{
printf("\nEnter data\t"); //printed twice
fgets(cp, 50, stdin); //not taking data
printf("\n%s",cp);
if(pid==0)
{ //CHILD PROCESS
close(readpipe[1]);
close(writepipe[0]);
read(readpipe[0],buf,sizeof(buf));
printf("\nSENT\n %s",buf);
write(writepipe[1],cp,strlen(cp)+1);
}
else
{ //PARENT PROCESS
close(readpipe[0]);
close(writepipe[1]);
write(readpipe[1],cp,strlen(cp)+1);
read(writepipe[0],buf,sizeof(buf));
printf("\nRECEIVED\n %s",buf);
}
printf("\nSEND SOMETHING TO CHILD PROCESS\t");
scanf(" %c",&ans);
}
close(readpipe[1]);
close(writepipe[0]);
close(readpipe[0]);
close(writepipe[1]);
return 0;
}
答案 0 :(得分:1)
你打电话
printf("\nEnter data\t"); //printed twice
fgets(cp, 50, stdin); //not taking data
在之前,检查您是在父进程还是子进程中。这当然会导致两个进程都打印,并且两者都是标准输入。因此,不清楚哪个进程会读取您输入的日期。
这些问题会出现同样的问题:
printf("\nSEND SOMETHING TO CHILD PROCESS\t");
scanf(" %c",&ans);
我建议你重新设计你的程序,以清楚地分离在父进程fork()
中运行的代码和在子进程中运行的代码。
答案 1 :(得分:0)
为什么fgets不接受数据? 在第一次扫描中,您正在读取单个字符,新行仍将在中 输入缓冲区,这将跳过
要解决这个问题,你应该使用scanf(“%[^ \ n]%* c”,&amp; ans) - 有关详细信息,请参阅this
找到修改过的代码..它可能会对你有所帮助(从我做出一些改变的时候打破,我验证了基本功能)
int main(void) {
pid_t pid;
int r;
/* Hope this is big enough. */
char buf[1024];
char cp[50];
char ans;
int readpipe[2];
int writepipe[2];
int a;
int b;
a=pipe(readpipe);
b=pipe(writepipe);
if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }
printf("\nSEND SOMETHING TO CHILD PROCESS\t");
scanf("%[^\n]%*c",&ans);
//ans = getchar();
fflush(stdin);
pid=fork();
if(pid==-1)
{
printf("pid:main");
exit(1);
}
while(ans=='y' || ans=='Y')
{
if(pid==0)
{
//CHILD PROCESS
close(readpipe[1]);
close(writepipe[0]);
if(read(readpipe[0],buf,sizeof(buf)) < 0)
{
break;
}
printf("\nChild Process Read: %s\n",buf);
printf("\n(child)Enter data:\t"); //printed twice
fgets(cp, 50, stdin); //not taking data
printf("\nData Written to Parent%s",cp);
if(!strncmp("Q",cp,1) || write(writepipe[1],cp,strlen(cp)+1) < 0)
{
break;
}
}
else
{
//PARENT PROCESS
close(readpipe[0]);
close(writepipe[1]);
printf("\n(Parent)Enter data\t"); //printed twice
fgets(cp, 50, stdin); //not taking data
printf("\nData Writtent to Child: %s",cp);
if(!strncmp("Q",cp,1) || write(readpipe[1],cp,strlen(cp)+1) < 0)
{
break;
}
if(read(writepipe[0],buf,sizeof(buf)) < 0)
{
break;
}
printf("\nParent Process Read: %s\n",buf);
}
ans ='y';
}
close(readpipe[1]);
close(writepipe[0]);
close(readpipe[0]);
close(writepipe[1]);
return 0;
}