我正在编写一个程序,其界面如下: myprog file1 file2 c
这个程序用execlp打开文件2创建两个子节点和P2,在这个文件上创建一个grep -c用于创建c并将结果提供给他的兄弟P1(我必须关闭STDOUT的FD并加入管道p2p1它们之间)。 P1从p2p1接收该值并将该值发送到P0。此外,这也与file1相同,并将结果提供给P0,它将打印它们。
问题是:父亲P0读了一些东西,但这是错误的。
我该怎么办?这是代码,感谢您的关注。
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#define MAX_STRING_LENGTH 128
/**************************/
/* DICHIARAZIONE FUNZIONI */
/**************************/
void wait_child();
void processo_p2(char *inputfile, char *c);
void processo_p1(char *inputfile, char *c);
/*********************/
/* VARIABILI GLOBALI */
/*********************/
int p1p0[2], p2p1[2];
int main(int argc, char* argv[])
{
int pid[2], i, value, count=0;
char *c, buf[10];
if (argc !=4)
{
fprintf(stderr, "Numero di argomenti errato\n");
fprintf(stderr, "Usage: %s file1 file2 C\n", argv[0]);
exit(EXIT_FAILURE);
}
c=argv[3];
/* Init */
pipe(p1p0);
pipe(p2p1);
for (i=0; i<2; i++)
{
pid[i] = fork();
if (pid[i] < 0)
{
fprintf(stderr, "P0: Errore nella fork");
exit(EXIT_FAILURE);
}
else if (pid[i] == 0)
{
if (i==0) /*P1*/
{
close(p1p0[0]);
close(p2p1[1]);
sleep(1);
processo_p1(argv[1], c);
close(p2p1[0]);
close(p1p0[1]);
exit(EXIT_SUCCESS);
}
else if (i==1)
{
close(p2p1[0]);
close(p1p0[0]);
close(p1p0[1]);
processo_p2(argv[2],c);
close(p2p1[1]);
exit(EXIT_SUCCESS);
}
}
else
{
printf("P0: created child P%d with PID %d\n", i+1, pid[i]);
close(p2p1[0]);
close(p2p1[1]);
close(p1p0[1]);
}
}
i=0;
int nread;
while ( (nread = read(p2p1[0], &buf[i], sizeof(char)) ) > 0 ) {
i++;
buf[i] = '\0';
printf("%s\n",buf);
for(i=0;i<2;i++)
{
wait_child();
}
return 0;
}
void processo_p2(char *inputfile, char *c)
{
int fd, nread, i=0, found=0;
char temp, row[100];
close(1);
dup(p2p1[1]);
execlp("grep", "grep", "-c", c, inputfile, (char *)0);
perror("P2: errorr in exec");
close(1);
}
void processo_p1(char *inputfile, char *c)
{
int fd, nrw, sk, nread, p2=0, i=0;
int value=1;
char temp, row[100], buf[10];
//RECEIVING DATA FROM P2 AND SENDING TO P0
while ( (nread = read(p2p1[0], &buf[i], sizeof(char)) ) > 0 ) {
i++;
}
buf[i] = '\0';
printf("from p2: %s\n",buf); //NOTHING STAMPED
write(p1p0[1],&buf,strlen(buf)+1);
close(1);
dup(p1p0[1]);
execlp("grep", "grep", "-c", c, inputfile, (char *)0);
perror("P1: errore in exec");
close(p1p0[1]);
}
void wait_child() {
int pid_terminated,status;
pid_terminated=wait(&status);
if (pid_terminated < 0)
{
fprintf(stderr, "%d\n", getpid());
perror("P0: errore in wait");
exit(EXIT_FAILURE);
}
if(WIFEXITED(status))
{
printf("P0: terminazione volontaria del figlio %d con stato %d\n",
pid_terminated, WEXITSTATUS(status));
if (WEXITSTATUS(status) == EXIT_FAILURE)
{
fprintf(stderr, "P0: errore nella terminazione del figlio pid_terminated\n");
exit(EXIT_FAILURE);
}
}
else if(WIFSIGNALED(status))
{
fprintf(stderr, "P0: terminazione involontaria del figlio %d a causa del segnale %d\n",
pid_terminated,WTERMSIG(status));
exit(EXIT_FAILURE);
}
}
答案 0 :(得分:0)
Trivia(但它会停止代码编译):最初显示的代码在错误的位置有一个紧密的括号 - 这些函数显然都嵌入在main()
中。最后一个大括号应该大大向上移动。
在启动子进程的循环中,您有父进程执行:
printf("P0: created child P%d with PID %d\n", i+1, pid[i]);
close(p2p1[0]);
close(p2p1[1]);
close(p1p0[1]);
在父进程中,紧接在循环之后,您有:
int nread;
while ( (nread = read(p2p1[0], &buf[i], sizeof(char)) ) > 0 ) {
i++;
buf[i] = '\0';
printf("%s\n",buf);
for(i=0;i<2;i++)
{
wait_child();
}
return 0;
}
&#39;很遗憾您关闭了您尝试阅读的文件描述符。父母应该从p1p0[0]
开始阅读,你确实已经开放了。
修正:
while
循环插入缺少的大括号,或移除其左大括号。评论中的问题与评论一样,具有难以理解的代码。但问题是你的循环太大了。
这就是我的main()
函数的固定版本的尾部:
…rest of loop to launch children…
else
{
printf("P0: created child P%d with PID %d\n", i + 1, pid[i]);
}
}
close(p2p1[0]);
close(p2p1[1]);
close(p1p0[1]);
i = 0;
int nread;
while ((nread = read(p1p0[0], &buf[i], sizeof(char)) ) > 0)
i++;
buf[i] = '\0';
printf("%s\n", buf);
for (i = 0; i < 2; i++)
{
wait_child();
}
return 0;
}
鉴于我已将源代码保存在文件pip.c
中并从中创建了程序pip
,因此生成了一个示例运行:
$ ./pip pip.c pip.c c
P0: created child P1 with PID 75458
P0: created child P2 with PID 75459
from p2: 49
49
P0: terminazione volontaria del figlio 75459 con stato 0
P0: terminazione volontaria del figlio 75458 con stato 0
$
我对所有换行都不满意,但至少会给出两次相同的答案,因为它显然应该是。